you use a hidden field with the name item_ids[]
and assign the item array to it.
Many to Many initializing relationship as default in Def New
-
20-07-2023 - |
Вопрос
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 %>
Решение