ruby on rails - ActiveRecord::RecordNotFound: Couldn't find Hotel without an ID -


i`ve got these errors while testing ratings_controller.

1) ratingscontroller create action creates rating if validations pass      failure/error: post :create, rating: {value: 4, user_id: user, hotel_id: hotel}      activerecord::recordnotfound:        couldn't find hotel without id      # ./app/controllers/ratings_controller.rb:6:in `create'      # ./spec/controllers/ratings_controller_spec.rb:12:in `block (4 levels) in <top (required)>'      # ./spec/controllers/ratings_controller_spec.rb:11:in `block (3 levels) in <top (required)>'    2) ratingscontroller create action not create rating if validations fail      failure/error: post :create, rating: {value: 3}      activerecord::recordnotfound:        couldn't find hotel without id      # ./app/controllers/ratings_controller.rb:6:in `create'      # ./spec/controllers/ratings_controller_spec.rb:17:in `block (3 levels) in <top (required)>'    3) ratingscontroller update action updates rating if validations ok      failure/error: patch :update, value: 3, user_id: user.id, hotel_id: hotel.id      actioncontroller::urlgenerationerror:        no route matches {:action=>"update", :controller=>"ratings", :hotel_id=>"1", :user_id=>"2", :value=>"3"}      # ./spec/controllers/ratings_controller_spec.rb:25:in `block (3 levels) in <top (required)>' 

i dont know come from. me please if can. ratings_controller:

class ratingscontroller < applicationcontroller   #before_action :signed_in_user   before_filter :authenticate_user!    def create     @hotel = hotel.find(params[:hotel_id])     @rating = rating.new(params[:rating])     @rating.hotel_id = @hotel.id     @rating.user_id = current_user.id     if @rating.save         redirect_to hotel_path(@hotel), :notice => "your rating has been saved"     end   end    def update     @hotel = hotel.find(params[:hotel_id])     #@rating = current_user.ratings.find(@hotel.id)     @rating = rating.find_by_hotel_id(@hotel.id)     if @rating.update_attributes(params[:rating])         redirect_to hotel_path(@hotel), :notice => "your rating has been updated"     end   end  end 

my ratings_controller_spec.rb:

require "spec_helper"  describe ratingscontroller   let(:rating) { factorygirl.create(:rating) }   let(:user) { factorygirl.create(:user) }   let(:hotel) { factorygirl.create(:hotel) }    describe "create action"     before { sign_in rating.user }     "creates rating if validations pass"       expect {           post :create, rating: {value: 4, user_id: user, hotel_id: hotel}          }.to change(rating, :count).by(1)     end      "does not create rating if validations fail"       post :create, rating: {value: 3}        expect(response).to redirect_to(hotel_path(hotel))     end   end    describe "update action"     before { sign_in hotel.user }     "updates rating if validations ok"       patch :update, value: 3, user_id: user.id, hotel_id: hotel.id       rating.reload       expect(rating.value).to eq(3);     end      "updates rating if validations fail"      end   end end 

especially third error confusing me because rake routes shows me avaible route ratings update action.

patch  /hotels/:id(.:format)       hotels#update put    /hotels/:id(.:format)       hotels#update 

thanks!

rails - 4.0.8 ruby - 1.9.3p551

update 1: sorry routes. mystake. copied wrong lines.

rating patch  /ratings/:id(.:format)    ratings#update         put    /ratings/:id(.:format)    ratings#update 

seems ok me , works fine if start server , test manually.

about id problem:

@hotel = hotel.find(params[:hotel_id]) expects params hash have top-level hotel_id key. when call create method test, nest hotel_id inside ratings key:

post :create, rating: {value: 4, user_id: user, hotel_id: hotel}

thus params[:hotel_id] nil. need add hotel_id top-level key:

post :create, rating: {value: 4, user_id: user, hotel_id: hotel}, hotel_id: hotel

alternatively, can pass nested hotel_id directly find method:

@hotel = hotel.find(params[:rating][:hotel_id])

about route problem:

your route mapped hotelscontroller (as seen in rake routes output hotels#update), testing ratingscontroller,

no route matches {:action=>"update", :controller=>"ratings", :hotel_id=>"1", :user_id=>"2", :value=>"3"}.

update routes route ratingscontroller's update method instead of hotelscontroller, have ratings#update route.

update:

in case, route expecting id parameter in url: /ratings/:id, not providing:

patch :update, value: 3, user_id: user.id, hotel_id: hotel.id

either provide specific rating id want update, or change routes not require id parameter since finding rating through hotel anyway, like

patch '/ratings', 'ratings#update'

instead of

patch '/ratings/:id', 'ratings#update'.

if defined routes resources :ratings, can put specific route above it, hit first router. idea exclude too: resources :ratings, except: :update. or use collection routes. see this question more info.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -