Question

In Rails 4.0 I have a many to many relationship of game, game_item (the look up table) and item. How do I initialize a default relationship to existing Items when creating a new Game?

game.rb:

class Game < ActiveRecord::Base
  has_many :game_items
  has_many :items, :through => :game_items
  accepts_nested_attributes_for :game_items
end

game_item.rb:

class GameItem < ActiveRecord::Base
  belongs_to :game
  belongs_to :item
  accepts_nested_attributes_for :item
end

item.rb:

class Item < ActiveRecord::Base
  has_many :game_items
  has_many :games, :through =>  :game_items
end

The items already exist in the database and do not need to be created but will need to be updated. When creating a new Game object I want to associate several Items with it.

games_controller.rb:

  # GET /games/new
  def new
    @game = Game.new
    @game.items = Item.all(:order => 'RANDOM()', :limit => 3)
  end

This seems to work as I view them in the games/new.html.erb with this code:

<p>
  <% @game.items.each do |item| %>
      <%= item.name %> 
  <%end %>
</p>

The problem is when saving the game, via the GameController#create method, the relationship does not save into the look up table game_items.

 # POST /games
  # POST /games.json
  def create
    @game = Game.new(game_params)

    respond_to do |format|
      if @game.save
        format.html { redirect_to @game, notice: 'Game was successfully created.' }
        format.json { render action: 'show', status: :created, location: @game }
      else
        format.html { render action: 'new' }
        format.json { render json: @game.errors, status: :unprocessable_entity }
      end
    end
  end

I believe it is the strong parameters which are not allowing the relationship to be saved although

  # Never trust parameters from the scary internet, only allow the white list through.
    def game_params
      #params.require(:game).permit( :correct, :incorrect,  :timed_out,  item_attributes: [:id, :name])[] )
      params.require(:game).permit( :correct, :incorrect,  :timed_out, :item_ids => [])

     end

I know that I can build the relationship again in the create with

  # POST /games
  # POST /games.json
  def create
    @game = Game.new(game_params)
    @game.items = Item.all(:order => 'RANDOM()', :limit => 3)
  ...

but since the items are random, I need to save the items that were presented to the user when they first initiated the game object with the new method.

How can I save the game_item relationship?

Edit:

Solution as suggested by @phoet. Use a hidden field to pass the array.

<% @game.items.each do |item| %>
    <%= f.hidden_field :item_ids, :multiple => true, :value => item.id %>
<% end %>
Était-ce utile?

La solution

you use a hidden field with the name item_ids[] and assign the item array to it.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top