This is probably basic stuff, but I really made my homework looking it up. I still can´t find the solution.
I have a users db, a movies db, and a ratings db. Ratings has a movie_id开发者_如何学运维, user_id and grade.
class Rating < ActiveRecord::Base
attr_accessible :grade
belongs_to :user
belongs_to :movie
end
class User < ActiveRecord::Base
has_many :ratings, :dependent => :destroy
has_many :movies, :through => :ratings
...
class Movie < ActiveRecord::Base
has_many :ratings, :dependent => :destroy
has_many :users, :through => :ratings
...
But I can´t create a rating with both movie_id and user_id
rails c test
Loading test environment (Rails 3.0.3)
@movie=Factory(:movie)
#<Movie id: 1, title: "Rocky 20", link: "#", created_at: "2011-01-22 21:04:42", updated_at: "2011-01-22 21:04:42">
@user=Factory(:user)
#<User id: 1, name: "lola", email: "lola@gmail.com", created_at: "2011-01-22 21:04:48", updated_at: "2011-01-22 21:04:48", encrypted_password: "c306a696138fa08c543ada3a3b4fd92067e9941743b7558e891...", salt: "f82c6abaccec17e2866d50150ad200181eb4bc8e0204249f171...", admin: false>
>> @user.ratings.create(:grade=> 4, :movie_id =>@movie.id)
=> #<Rating id: 1, grade: 4, user_id: nil, movie_id: nil, created_at: "2011-01-22 21:04:55", updated_at: "2011-01-22 21:04:55">
that "movie_id: nil" is what is killing me...
then of course me tests are not passing: @user.rating.create(grade => 5, :movie_id => @movie.id) has no movie_id @movie.rating.create(grade => 5, :user_id => @user.id) has no user_id
any hints?
Thanks!!
The code you're showing here should absolutely work IMO. Which leaves me guessing that it's something you aren't showing here. A couple of things I'd try:
- Use the regular console for a change
- Don't use Factories (maybe it's them?), create actual entries instead
I've tried your example and here's what I got:
> m = Movie.create :title => "Foo"
=> #<Movie id: 1, title: "Foo", created_at: …>
> u = User.create :name => "Marc"
=> #<User id: 1, name: "Marc", created_at: …>
> u.ratings.create :grade => 4, :movie_id => m.id
=> #<Rating id: 1, grade: 4, user_id: 1, movie_id: 1, created_at: …>
> m.ratings.create :grade => 3, :user_id => u.id
=> #<Rating id: 2, grade: 3, user_id: 1, movie_id: 1, created_at: …>
Which you can also use like this, as you might know:
> m.ratings.create :grade => 3, :user => u
=> #<Rating id: 3, grade: 3, user_id: 1, movie_id: 1, created_at: …>
Try defining your factories like this:
Factory.define :movie, :class => Movie do |f|
f.title "Rocky 20"
f.link "#"
end
Factory.define :user, :class => User do |f|
f.name "Lola"
f.email "lola@gmail.com"
end
Factory.define :rating, :class => Rating do |f|
f.movie { |m| m.association :movie}
f.user { |u| u.association :user}
f.grade 4
end
Then to test a rating, use the rating factory by itself:
it "creates a rating" do
rating = Factory.create(:rating)
rating.user.name.should == "Lola"
rating.movie.title.should == "Rocky 20"
end
精彩评论