|
|
||
これある意味マルチポストなのかなぁ…。
こんなの作ります。
どっかで見たことある感じですね!すいません真似しました><
検索がない一覧なんて一覧じゃない!ということで
scaffoldに検索機能をつけたものを作りたいと思います。
おまけとしてセレクトボックスも付いてます。
長いので始めに結果を書いておきます。
実装約20分!
正直10分くらいでできると思ってたんですが、それなりに時間がかかってしまいました。
検索に関してはほんのさわり程度です、実装の方法は他にもあると思います。
むしろ僕にベストな方法を教えてくだs(ry
とりあえずやったことをつらつらと書いて行きたいと思います。
何はともあれrailsコマンド
メインとなるtodoモデル関連を作成
ruby script\generate scaffold todo name:string
セレクトボックスにぶちこむcategoryマスタのモデルを作成
ruby script\generate model category label:string
todoマイグレーションファイルに、categoryとの関連を書きます。
t.belongs_to :category
モデルにも書いておく
belongs_to :category
画面を確認しておく。
いくらIDEを使っていようと、やはりスクリプト言語なので細かいチェックは欠かせません。
ちなみに僕は、categoryのスペルを間違っていてエラーもらいました・・・。
これではまだ画面はいつものままなので、セレクトボックスを追加します。
<%= f.text_field :name %>これは元々追加されてるはずなので、その下あたりに以下を追加
<%= f.collection_select(:category_id, Category.find(:all), :id, :label) %>
collection_selectの、第一引数はコントローラ側で受け取るときのキーになります
第二引数はコレクションを、
第三引数はvalueにバインドするフィールド、第四引数は表示するフィールドを入れます。
これでセレクトボックスが表示されます。
ですがこのままだと中身が空なので、
ruby script\generate migration add_category_data
として、テストデータ作成用のマイグレーションファイルを作成します。(コンソールで入れてもokです
upメソッドの中に、以下を追加します。
Category.create :label=>'Task', :id=>1
Category.create :label=>'Ploblem', :id=>2
rake db:migrateを実行するとセレクトボックスの中に値が入ってるいるはずです。
ついでに変更画面にも新規画面と同じコードを追加しておきます。
これでもうtodoとcategoryを関連付けたデータが作成可能です!
ここまで約10分!予想以上に時間かかったな・・・。
index画面に以下を追加します。
あれ、categoryはjoinしてないよね?
ARは遅延読み込みをサポートしているので、このままでも動きます!
当然、先に読み込んでおくことも可能です。
これで、一覧画面でもcategoryを参照できるようになったはずです
todoのnameに対して、必須のバリデーションをかけておきます。todoモデルに以下を追加すればOK
validates_presence_of :name
index画面に以下を追記しておきます。
<span style="font-weight:bold;"><tr style="background-color:<%=cycle("red", "yellow")%>"></span>
cycleというのは、呼ばれる毎に引数の値を順番に表示してくれるメソッドです。
検索フォームを作成する方法はいろいろありますが、今回はform_tagを使います。
index画面に以下を追加
<%form_tag :action=>"search" do%>
<%=text_field_tag :keyword, @keyword%>
<%=select_tag :category_id, options_from_collection_for_select(Category.find(:all), :id, :label, @category_id.to_i)%>
<%=submit_tag "検索"%>
<%end%>
セレクトボックスの作成の仕方が先ほどと少し異なっています。
options_from_collection_for_selectというのは、"<option value="・・・">・・・</option>"を、指定したコレクションサイズの分だけ作ってくれます。
コントローラに以下を追加
def search
@todos = Todo.find(:all,
:conditions=>["name like ? and category_id = ?", "%#{params[:keyword]}%", params[:category_id]]
)
@keyword, @category_id = params[:keyword], params[:category_id]
render :action=>:index
end
text_field_tag :keywordに入力した値が、params[:keyword]によって取得できます。
@keyword, @category_id = params[:keyword], params[:category_id]で、値をインスタンス変数に入れなおしているのは、検索実行後にも検索条件を保持するためです。
これで検索ができるようになるはずです!
ここまで約20分!
ActiveRecordで動的にクエリーを作成するのは意外と難しいです。ここでnamed_scopeの出番なわけですが、それはまた今度ということで・・・。
実際は、以下のような感じで実装したのですが、毎回DBアクセスが走るのはよろしくないなぁ。
validates_inclusion_of :category_id,
:in => Category.find(:all).map{|i| i.id}
セレクトボックスを作成する箇所をhelperに移動する、部分テンプレートを用いてeditとnewの重複を省く、などなど。
Elyza2011/09/08 07:36I thought finding this would be so aruodus but it's a breeze!
tuixdds2011/09/08 16:43w6qRSt <a href="http://hglzpjqktjul.com/">hglzpjqktjul</a>
clqdlbym2011/09/10 19:06Q5bpa4 <a href="http://avphjcuynisb.com/">avphjcuynisb</a>
jwznyt2011/09/12 19:18hi2R4I , [url=http://dxpsdklfycpr.com/]dxpsdklfycpr[/url], [link=http://kdumyutxhjcd.com/]kdumyutxhjcd[/link], http://suoqwdxeyiyk.com/
知って得した便利文法 on Ruby - kelkronsoの日記
他にもこんなのあるよ!というのがあればコメントでよろしくお願いします!
自己代入
a ||= 1 # a が偽か未定義ならば1を代入。
↓こんな感じで
#インスタンス変数modelを取得する、modelがnilの場合はインスタンス化したものを返す def model @model ||= Model.new end
多重代入
a, b, c = 1, 2, 3 #a=1, b=2, c=3
あまり横に長くなるようなら素直に縦に書いたほうがいいかもしれませんね。
setter
def method_name=(arg) @arg = arg end
こんな感じで使える!
C#のプロパティみたいな感じですね。
"!"を極力使わない
if式のthenは省略する。また、if !xのような場合は、 unless xに置き換える。ただし、unlessの場合、 elseは使用しない。また、条件が十分に簡単で、一行で書ける場合は、if/while修飾子を使用してもよい。
Rubyコーディング規約
ばりばり使ってたら怒られました・・・。
はてなグループって、はてなダイアリーで書いた記事がグループに対してリンク貼られるー
といった感じの機能かと思っていたら、こっちはこっちで記事書かなきゃいけないのか!
というわけで自分の記事に対してリンク張ってみる
http://d.hatena.ne.jp/kelkronso/20080608/1212891488:title
Rails使いの方々からのコメント待ってます><
第一引数
インスタンス or 文字列 or シンボルを指定
(配列でもいけるっぽいけど、どんなときに使うんだろうか
アクション先で取得するハッシュのキーには (param[:key]こんな感じで
第一引数が文字列、シンボルならその文字列が
インスタンスならそのクラス名が使われる(と思われる
オプションいろいろ
methodの指定
アクション先の指定
scaffoldを作成したときにできるviewは、newもeditも、下記のようになっている
<% form_for(@article) do |f| %>
なのにアクション先がcreateかupdateかに分岐できるかというと
インスタンスのnew_record?を見て判断しているから
というわけで
ActiveRecordを継承していないクラスを引数に使うときに
new_record?メソッドで適切な値を返してやると、form_forをうまくだますことができる。
(けどここまでやるなら違う方法でやったほうがいいよなー。