我试图在非资源路由的RSpec测试中将ID传递给get方法,并且我得到一个参数错误。
以下是测试:
describe MoviesController do
describe "search directors" do
it 'calls the model method that find similar movies' do
movie1 = Movie.create(:title => "Star Wars1", :director => "George", :rating => "R")
movie2 = Movie.create(:title => "Star Wars2", :director => "George", :rating => "R")
get :search_directors, {:id => 1}
end
end
end
MoviesController中的search_directions动作:
def search_directors
@movie = Movie.find(params[:id])
@movies = Movie.similar_movies(@movie)
end
这是我的路线:
Rottenpotatoes::Application.routes.draw do
resources :movies
root :to => redirect('/movies')
get '/movies/search_directors/:id', to:'movies#search_directors'
end
电影模特(movie.rb)
class Movie < ActiveRecord::Base
def self.all_ratings
%w(G PG PG-13 NC-17 R)
end
def self.similar_movies
Movie.where(director: self.director)
end
end
错误:
Failure/Error: get 'search_directors', {:id => 1}
ArgumentError:
wrong number of arguments (given 1, expected 0)
# ./app/models/movie.rb:5:in `similar_movies'
# ./app/controllers/movies_controller.rb:66:in `search_directors'
# /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.6/lib/action_controller/metal/implicit_render.rb:4:in `send_action'
# /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.6/lib/abstract_controller/base.rb:198:in `process_action'
# /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.6/lib/action_controller/metal/rendering.rb:10:in `process_action'
# /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.6/lib/abstract_controller/callbacks.rb:20:in `block in process_action'
答案 0 :(得分:0)
是的,问题出在这里......
def self.similar_movies
Movie.where(director: self.director)
end
没有课程方法director
,而且你没有传递实例。解决这个问题的一种方法......
def self.similar_movies(movie)
Movie.where(director: movie.director)
end
但更好的方法是将其作为实例方法......
def similar_movies
Movie.where(director: self.director)
end
然后你可以替换......
@movies = Movie.similar_movies(@movie)
有更好的......
@movies = @movie.similar_movies
您甚至不需要控制器中的search_directors
方法,只需参考(在您的视图中)@movie.similar_movies
进一步建议的改进... similar_movies
您可能不希望在返回的集合中包含self
(主要电影不应出现在类似电影列表中) ,所以:
def similar_movies
Movie.where(director: director).where.not(id: id)
end
注意(顺便说一下)使用director
很好,您不需要self.director
。在完成作业时,您只需要self
。
# creates a local variable
director = "Alfred"
# updates the model attribute
self.director = "Alfred"