この一連のエントリは
Ruby on Rails 3 Tutorial: Learn Rails by Example (Addison-Wesley Professional Ruby Series)
で参考に学んだことを凝縮してお送りしています。
Ruby on Rails 3 Tutorial: Learn Rails by Example (Addison-Wesley Professional Ruby Series)
で参考に学んだことを凝縮してお送りしています。
まずはUserモデルを編集します。
validatesをしている辺りに以下の行を追加します。
has_many :fans, :foreign_key => "user_id",has_manyは1対多関係における1側(多を持つ側)を表します。
:dependent => :destroy
has_many :movies, :through => :fans
Userモデル1つにつき複数のfanモデル、movieモデルを持つことを意味します。
has_manyのパラメータは複数形になります(fans, movies)。
これでuser.fansとするとfanオブジェクトの配列にアクセスできます。
foreign_keyは外部キーを指定します。
「:dependent => :destroy」はUserモデルを削除したときに連動して該当するuser_idのFanテーブルの項目を削除するように指定します。
2行目のhas_many文は「user.movies」とすることでそのユーザーが好きな映画の配列にアクセス可能とするための文です。userとmovieの間は直接ではなくFanテーブルを間に挟んでいます。user_idとmovie_idをフィールドに持つFanテーブルを通じてUserテーブルとMovieテーブルの多対多関係を表しています。
こうすることでuser.moviesとするだけで、そのユーザーの好きな映画情報にアクセスできます。
では次にapp/model/fan.rbを編集します。
class Fan < ActiveRecord::Base1対多の多側(相手が1つ)なのでbelongs_toで相手側モデルを指定します。
belongs_to :user
belongs_to :movie
validates :user_id, :presence => true
validates :movie_id, :presence => true
end
belongs_toのパラメータは単数になります(user, movie)。
そしてMovieモデルを編集します。
以下の2行を追加します。
has_many :fansUserモデルで定義した内容と逆方向です。
has_many :users, :through => :fans
これでmovie.usersとすることでその映画を好きだといっているユーザー配列にアクセスできます。
次にuserモデルに好きな映画を登録する機能を追加しましょう。
まずはspec/model/user_spec.rbにテストコードを追加します。
beforeブロックの赤字部分と、以降の検査コードを追加します。
describe "fans" do
before(:each) do
@user = Factory(:user)
@movie = Factory(:movie)
end
〜(省略)〜
it "favorite_movie!メソッドが機能すること" do
@user.should respond_to(:favorite_movie!)
end
it "unfavorite_movie!メソッドが機能すること" do
@user.should respond_to(:unfavorite_movie!)
end
it "favorite?メソッドが機能すること" do
@user.should respond_to(:favorite?)
end
it "追加した映画が登録されていること" do
@user.favorite_movie!(@movie)
@user.movies.should include(@movie)
end
it "削除した映画が登録されていないこと" do
@user.favorite_movie!(@movie)
@user.unfavorite_movie!(@movie)
@user.movies.should_not include(@movie)
end
ここでは好きな映画を登録する「favorite_movie」、解除する「unfavorite_movie」、さらにその映画が好きかどうかを返す「favorite?」メソッドが存在するかどうかといったことなどをチェックしています。
では対応するコードをapp/model/user.rbに定義しましょう。
では対応するコードをapp/model/user.rbに定義しましょう。
def favorite_movie!(movie)
fans.create!(:movie_id => movie.id)
end
def unfavorite_movie!(movie)
fans.find_by_movie_id(movie).destroy
end
def pushed?(member)
members.include?(member)
end
「favorite_movie!」ではFanモデルのインスタンスを新たに生成しています。
「unfavorit_movie!」では渡されたmovieのidからfanインスタンスを検索して、該当するfanモデルを削除します。
「unfavorit_movie!」では渡されたmovieのidからfanインスタンスを検索して、該当するfanモデルを削除します。
0 件のコメント:
コメントを投稿