2017-04-20 101 views
1

我協會工作不軌道4:模型關聯並不在Rails的4個工作

review.rb

class Review < ActiveRecord::Base 
    belongs_to :movie, :class_name => "Movie", :foreign_key => "movie_id" 
    belongs_to :moviegoer 
    # review is valid only if it's associated with a movie: 
    validates :movie_id, :presence => true 
    # can ALSO require that the referenced movie itself be valid 
    # in order for the review to be valid: 
    validates_associated :movie 

end 

movie.rb

class Movie < ActiveRecord::Base 
    has_many :reviews 
    before_save :capitalize_title 

    def capitalize_title 
    self.title = self.title.split(/\s+/).map(&:downcase). 
     map(&:capitalize).join(' ') 
    end 

    scope :with_good_reviews, lambda { |threshold| 
    Movie.joins(:reviews).group(:movie_id). 
     having(['AVG(reviews.potatoes) > ?', threshold.to_i]) 
    } 
    scope :for_kids, lambda { 
    Movie.where('rating in (?)', %w(G PG)) 
    } 

    scope :recently_reviewed, lambda { |n| 
    Movie.joins(:reviews).where(['reviews.created_at >= ?', n.days.ago]).uniq 
    } 

    def self.all_ratings ; %w[G PG PG-13 R NC-17] ; end # shortcut: array of strings 

    validates :title, :presence => true 
    validates :release_date, :presence => true 
    validate :released_1930_or_later # uses custom validator below 
    validates :rating, :inclusion => {:in => Movie.all_ratings}, 
    :unless => :grandfathered? 

    def released_1930_or_later 
    errors.add(:release_date, 'must be 1930 or later') if 
     release_date && release_date < Date.parse('1 Jan 1930') 
    end 

    @@grandfathered_date = Date.parse('1 Nov 1968') 

    def grandfathered? 
    release_date && release_date < @@grandfathered_date 
    end 
end 

reviews_controller.rb

class ReviewsController < ApplicationController 
    before_filter :has_moviegoer_and_movie, :only => [:index, :new, :create] 
    protected 
    def has_moviegoer_and_movie 
    unless @current_user 
     flash[:warning] = 'You must be logged in to create a review.' 
     redirect_to '/auth/twitter' 
    end 
    unless (@movie = Movie.where(:id => params[:movie_id])) 
     flash[:warning] = 'Review must be for an existing movie.' 
     redirect_to movies_path 
    end 
    end 
    public 

    def index 
    @reviews = @movie.reviews 
    render(:partial => 'review', :object => @reviews) if request.xhr? 
    end 

    def new 
    @review = @movie.reviews.build 
    end 
    def create 
    # since moviegoer_id is a protected attribute that won't get 
    # assigned by the mass-assignment from params[:review], we set it 
    # by using the << method on the association. We could also 
    # set it manually with review.moviegoer = @current_user. 
    @current_user.reviews << @movie.reviews.build(params[:review]) 
    redirect_to movie_path(@movie) 
    end 
end 

在審查控制器何時我嘗試訪問@ movie.reviews,它應該返回屬於該電影的所有評論的列表,但是我得到一個錯誤,指出「電影」錯誤的「未定義方法」評論。這裏發生了什麼?這應該是正確的?我還建立了這樣

resources :movies do 
    resources :reviews 
end 
+0

哪條線給你的錯誤?這個'@current_user.reviews << @ movie.reviews.build(params [:review])'? – dezull

+0

'@review = @ movie.reviews.build'或'@reviews = @ movie.reviews'是給我的錯誤,取決於我嘗試運行哪一個動作 – Xcelleratr

回答

1

行嵌套的路線:

unless (@movie = Movie.where(:id => params[:movie_id])) 

ActiveRecord_Relation而不是記錄實例。你應該這樣做:

unless (@movie = Movie.find(params[:movie_id])) 

代替