Fail to pass id to foreign table

I'm working on a videogame database, where users can signup, make game entries, rate and review them.

I have the Models: User, Game, Rating and Review. Each user can give his own rating to any game, so I have to pass the game.id to the ratings.game_id in order to associate ratings to certain games.

And I would like to think that it should work the same way about posting reviews, but every time I the game.id shall be passed, get a Runtime Error

"Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id"

This is what my associations in my models look like

  user.rb   has_many :reviews, dependent: :destroy   has_many :reviewed_games, :through => :reviews, :source => :games

  game.rb   has_many :reviews   has_many :authors, :through => :reviews, :source => :users

  review.rb   belongs_to :user   belongs_to :game

This is my review controller   def create     @game = Game.find_by_id(params[:game_id])     @review = current_user.reviews.build(params[:review])     @review.game_id = @game.id     @review.user_id = current_user.id

    if @review.save       flash[:success] = "review created!"       redirect_to @review     else       render 'new'     end   end

And my Form <%= form_for(@review) do |f| %>   <div class="field">     <%= f.text_area :content, placeholder: "Compose new review..." %>   </div>   <%= hidden_field_tag("game_id", @game.id) %>   <%= f.submit "Post", class: "btn btn-large btn-primary" %> <% end %>

The Runtime Error occurs, once I try to open the reviews/new url. When I dismiss the hidden_field_tag, I receive the review form, but now posting causes the exact same error (because of the game.id in the create method).

I really can't explain why this is happening, because the very same way my whole rating feature is programmed and it works just fine.

Can you Guys help me out?

The error message should tell you which line of code is causing the error. The problem is that whatever you are calling .id on at that line of code is nil.

Have a look at the Rails Guide on Debugging and it will show you techniques that you can use to debug your code.

Colin

All right, thanks for pointing that out.

I simply used <%= debug @review %>

in my new-View of the reviews controller.

Revieweing a game works by clicking on the "review" button in "game#show".

So having <%= debug @review %> in game#show, game_id receives it's proper id, but once I open the new Form (which is the url reviews/new) there is no number behind the reviews game_id.

So what can I do about it? I guess I have to modify my Routings, because rating works directly on game#show, while reviewing opens it's own page.

how do I pass the game ID to the review model in my routes? So far all I have is "resources :reviews" :confused:

Sorry I don't know what you mean by that. Note that a url does not open a form, it runs an action, which may then show a view with a new form. When explaining a problem it is important to explain exactly where the problem lies and if necessary show the problem code. Not all the code just the small part that is not doing what you expect.

Colin

All right.

the show view of a single game has the url (games/:id). when I pste "debug @review" in the show view, it says that the review game_id has the id of the current game shown.

Opening the review Form (which is the "new Method of the review controller), the debug result shows, that now there is no game_id for the review, because I'm opening a form, that is not associated to the game, but simply looks like this "localhost:3000/reviews/new"...so the form doesn't know which game_id the review should belong to.

So I need to route the review form to the game where I opened the review form. This means that a url needs to be created like this "localhost:3000/games/4/reviews/new".

How do I do that? I tried the approach with nested resources, like this

  resources :games do     member do        :reviews     end   end

but now my helper methods like "new_review_path" are not working.

I hope you understand what my problem is and can give me a hint about routing.

I appreciate any kind of help!

Why would you expect them to? Run `rake routes` to see what your paths look like with nested resources.

oh you are right of course.

well rake routes shows following:

reviews_game GET /games/:id/reviews(.:format) games#reviews

but I'm still confused, because this is the only route associated to my reviews, but shouldn't there be routes for "new" and "show" and "edit"? I thought I created a nested resource!?

also using the helper method "reviews_game_path" now causes me an unknown action. I think i'm on the right way but I'm still missing out on something.

I still have to learn a lot about routes.

So can I simply replace the ":reviews" with several "match" lines? Or do I actually need something else than "member"?

Update:

Allright I tried this

  resources :games do     member do       get :followers     end     resources :reviews   end

(the member is for following purposes and has nothing to do with reviews)

Now paths like "new_game_review_path" are generated, but now when I want to open a view, that contains this helper path, I get this routing error: No route matches {:action=>"new", :controller=>"reviews"}

now what kind of method does my review controller need? or should I adjust my routings a little bit more? But I thought every method in the reivew controller should be available with these routings :confused:

Allright I fixed this problem to. my helper path simply needed the game parameter

new_game_review_path(@game)

The form for creating a new review looks now like this

<%= form_for(@review, :url => game_reviews_path(@game)) do |f| %>

But unfortunately I end up with the same problem. the game object is still nil and I can't get the game_id :confused:

having this hidden_field_tag in my form causes me the "object is nil" error

        <%= hidden_field_tag("game_id", @game.id) %>

I thought the games id would automatically be passed to its nested resource, once I got my routings right, but I still can't pass the game objects id to my review table :confused:

Allright I fixed this problem to. my helper path simply needed the game parameter

new_game_review_path(@game)

The form for creating a new review looks now like this

<%= form_for(@review, :url => game_reviews_path(@game)) do |f| %>

But unfortunately I end up with the same problem. the game object is still nil and I can't get the game_id :confused:

having this hidden_field_tag in my form causes me the "object is nil" error

        <%= hidden_field_tag("game_id", @game.id) %>

Do you mean @game is nil? In that case you are not setting it up in the controller.

Colin

my controller looks like this

  def create     @game = Game.find_by_id(params[:id])     @review = current_user.reviews.build(params[:review])     @review.game_id = @game.id     @review.user_id = current_user.id

    if @review.save       flash[:success] = "review created!"       redirect_to @review     else       render 'new'     end   end

  def new     @review = Review.new(params[:review])   end

but it seams that @game can't be located in the url "localhost:3000/games/1/reviews/new" even though I think I set the form path correct

In "reviews#new" the game object still seems to be unknown :confused: