ArgumentError传递RSpec get方法一个参数

时间:2016-10-07 20:50:27

标签: ruby-on-rails rspec

我试图在非资源路由的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'

1 个答案:

答案 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"
相关问题