2012-04-23

active scaffoldのfield_searchを使うときhas_manyで関連している先のテーブルの複数のカラムを検索対象にする

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
ActiveScaffoldでfield_searchを使うときのお話です。

以下のようなモデルがあるとします。

class Order < ActiveRecord::Base
  has_many :items
end

class Item < ActiveRecord::Base
  belongs_to :order
end

Orderに対してActiveScaffoldを設定して、検索する際にOrderの情報だけでなくItemのコードや名称も検索したい場合です。
field_searchでなく、通常のsearchならば

config.columns[:items].search_sql = "concat(items.code,' ',items.name)"
みたいな設定をしてitemsをsearch対象に入れてあげればOKです。

field_searchの場合で、itemsの一つのカラムだけであれば
同じように
config.columns[:items].search_sql = "items.code"
でできるのですが、items.codeとitems.nameの両方の検索用テキストボックスを表示したい場合は、以下のように
ダミーカラムを用意することと検索条件を上書きすることで、できるようになります。

ここではダミーカラム、item_codeとitem_nameを定義しています。このカラムはorders、itemsにも存在しないカラムです。
一部記述を省略しています。
class OrderController < ApplicationController
  active_scaffold :orders do |config|
    config.label = "オーダー管理"

    config.actions.exclude :search
    config.actions.add :field_search

    config.columns = [...
                      :item_code,
                      :item_name]
    ...
    config.columns[:item_code].label = "商品コード"
    config.columns[:item_code].search_sql = ""
    config.columns[:item_name].label = "商品名"
    config.columns[:item_name].search_sql = ""

    #ダミーカラムを表示しないようにします
    config.list.columns.exclude [:item_code,:item_name]
    config.show.columns.exclude [:item_code,:item_name]
    config.create.columns.exclude [:item_code,:item_name]
    config.update.columns.exclude [:item_code,:item_name]

    #ダミーカラムを検索で利用します。
    config.field_search.columns = [:item_code,:item_name]
    config.field_search.text_search = false

    config.nested.add_link(:items,:label => "商品")
  end

  #ダミーカラムitem_codeを利用した検索条件
  def self.condition_for_item_code_column(column, value, like_pattern)
    ["orders.id in (select distinct order_id from items where where code = ?))", value.strip]
  end

  #ダミーカラムitem_nameを利用した検索条件
  def self.condition_for_item_code_column(column, value, like_pattern)
    ["orders.id in (select distinct order_id from items where where name = ?))", value.strip]
  end

end

データ量が多いテーブルにActiveScaffoldを使う時、検索はfield_searchがよさげ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
データ量が多いテーブルにActiveScaffoldを使うときの場合です。

たとえば、以下のようなテーブルがあるとします。

table名:logs
カラム
id
ip_address
user
page

普通にActiveScaffoldを設定すると検索は、テキストボックス一つ表示され
ここに10.10.10.10とか入れた場合、以下のようなSQLが発行されます。
select id from logs where ip_address like '%10.10.10.10% or user like '%10.10.10.10% or page like '%10.10.10.10%

データ量が少ないときは、一つの条件で複数のカラムを探すので便利なのですが
データ量が多くなるとindexが効かないので遅くなっていきます。

そんなときは、通常の検索のsearchではなくて、field_searchを使うのがよさげです。
field_searchの場合は、各カラム毎に検索用のテキストボックスが表示され、それぞれ個別に条件を指定することになります。
デフォルトではsearchと同じような検索になってしまうのですが、設定で完全一致にできてindexを効かせることができるようになります。

以下は、field_searchの設定例です。
class LogController < ApplicationController
  active_scaffold :logs do |config|
    config.label = "ログ情報"

    config.actions.exclude :search
    config.actions.add :field_search

    config.columns = [:ip_address,
                      :user,
                      :page]
    config.columns[:ip_address].label = "IPアドレス"
    config.columns[:user].label       = "ユーザ"
    config.columns[:page].label       = "ページ"
    config.show.columns << [:created_at,:updated_at]

    config.field_search.columns = [:ip_address,:user,:page]
    #ここで完全一致検索に設定
    config.field_search.text_search = false
  end
end

2012-04-13

railsのbefore_saveでbooleanの値をセットしようとしたらエラーになってしまった

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
rails2.3でのお話です。

あるモデルに以下のようにbooleanの値を設定するbefore_saveを作成しました。

def before_save
  if age >= 20
    a_flag = true
    c_flag = false
  end
end

これでageが20以上のデータを保存しようとしたら、できなったのです。
エラーログを見ても何もでていません。

気づく人はすぐ気づくのでしょうが、私は無駄に時間を食ってしまいました・・・

これは、以下のようにすれば問題なくなります。

def before_save
  if age >= 20
    a_flag = true
    c_flag = false
    true
  end
end

before_saveなどは戻り値としてfalseを返すと、アクションをキャンセルすることができます。
最初のbefore_saveだと、ageが20以上の場合は、最後に実行されるのが

c_flag = false


となり、最後に実行したものがbefore_saveの戻り値になり、この場合はfalseを返してることになっていたので失敗していたという感じでした。


2012-04-07

カッティングマシン silhouette CAMEO(シルエットカメオ)がキニナル

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

プリンタ感覚で紙とかをカットできてしまうキニナル、カッティングマシンというものです。
Craft ROBOという同様な製品があるなぁと思ったのですが同じ会社さんから出ているようです。
そしてCraft ROBOの方は販売終了の模様です。
詳しくは、以下で見れますです。
http://silhouettejapan.jp/index.html

2012-04-03

WBS「トレたま」で放送された商品をAmazonで検索してみた(201203放送分)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
WBSのコーナーの「トレたま」で放送された商品をAmazonで検索してみました。
今月は、かどまるPROがキニナルのです。

伝統技術で新素材 (放送:3月30日)
見つかりませんでした

血管が透け透けに♪ (放送:3月29日)
見つかりませんでした

バーコードなしでOK♪ (放送:3月28日)
見つかりませんでした

気になる胸元をカバー♪ (放送:3月27日)
見つかりませんでしたが、似たようなものがありました
   

お茶から再利用 (放送:3月26日)
見つかりませんでした

移動式浄水システム (放送:3月23日)
見つかりませんでした

花粉を抑える (放送:3月22日)
見つかりませんでした

新幹線のスリッパ (放送:3月21日)
見つかりませんでした

うずまき鍋?! (放送:3月20日)
見つかりませんでした

タイヤに印刷! (放送:3月19日)
見つかりませんでした

頭を守るエコバッグ (放送:3月16日)
見つかりませんでした

携帯型浄水器 (放送:3月15日)
見つかりませんでした

小型製紙装置 (放送:3月14日)
見つかりませんでした

どこでも蓄電池 (放送:3月13日)
見つかりませんでした

名刺管理アプリ (放送:3月12日)
見つかりませんでした

手軽な“タワー” (放送:3月9日)
amazonにありました
   

あたふたしないフタ (放送:3月8日)
見つかりませんでした

竹でできた自転車 (放送:3月7日)
見つかりませんでした

カドを丸くするカッター (放送:3月6日)
amazonにありました


電気のいらない自動ドア (放送:3月5日)
見つかりませんでした

うるさくないカラオケマイク (放送:3月2日)
うるさくないカラOK! ミュートマイク
見つかりませんでした
amazonにありました
 

楽らく 洗濯物ハンガー (放送:3月1日)
見つかりませんでした