Sir Jay
Sir Jay

Reputation: 59

pass an object's id to another nested object

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

In order to review a certain game, the review object needs to get the game's id, to be associated to this particular game. I have defined a nested resource

  resources :games do
    resources :reviews
  end

And in the show-view of a game I have a link, that leads to the review form

link_to "Kritik verfassen", new_game_review_path(@game)

The form itself is defined like this

<%= form_for(@review, :url => game_reviews_path(@game)) 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 %>

But this throws me the Runtime Error: "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id"

I don't understand why. my url looks like this "localhost:3000/games/:id/reivews/new" and as defined in the form, the url gets the "@game" attribute.

This is my reviews controller

  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
    #@review = @game.reviews.build(params[:review])
    #@review.game_id = Game.find_by_id(params[:game_id])


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

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

My associations in my models are set correctly, but why does my review form not receive the corresponding games id? It only works if I dismiss the "hidden_field_tag" but I need the game id. Also then the error occurs on creating the review, since a game.id is passed in the controller. Why is the game.id nil and how do I get it set in this nested url?

I appreciate any kind of help!

Upvotes: 0

Views: 814

Answers (2)

Sir Jay
Sir Jay

Reputation: 59

Oh yeah now it's working! Thank you so much. But I have to admit the controller looks a little bit dedundant now

  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 root_url
    else
      render 'new'
    end
  end

  def new
    @review = Review.new(params[:review])
    @game = Game.find_by_id(params[:game_id])
    @review.game_id = @game.id
  end

Is there anything that can be dismissed? Also now every review has a game_id in my database, but I'm still having the issue, that a review is only listed on a game, which id is equal to the users (authors) id.

Example: I'm trying to review a Game with the ID 4 and I am a user with the id=2...when posted the review is not display at game number 4, but at the game with the id 2. Even though as seen in my database the review gets the correct game_id, but it is not associated to the game, but the users id is...

I think something about the "show" method in my games controller has to be modified

currently its looking like this

  def show
    #store_location
    @game = Game.find(params[:id])
    @review = @game.reviews.build
    @feed_items = @game.feed.paginate(page: params[:page])
    #@reviews = @user.reviews.paginate(page: params[:page])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @game }
    end

  end

Upvotes: 0

Krishna
Krishna

Reputation: 58

I find two issues here, in your form

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

no need to pass @game you just need :url => game_reviews_path

check your rake routes for find the exact path helpers

second, from the game_id hidden field tag

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

your params[:game_id] will give the id of game, but in your create action you are doing this

 @game = Game.find_by_id(params[:id])

Upvotes: 1

Related Questions