Let's imagine we want to assign pokemons to trainers.
We are creating a new_trainer form with checkboxes for each pokemon and their names next a checkbox to assign them to this new trainer, like this:
- Salameche
- Ratata
- Roucool
So we've got this :
class Pokemon
has_many :pokeballs
has_many :trainers, through: :pokeballs
end
class Pokeball
belongs_to :pokemons
belongs_to :trainers
end
class Trainer
has_many :pokeballs
has_many :pokemons, through: :pokeballs
end
class TrainersController < ApplicationController
def new
@trainer = Trainer.new
end
def create
@trainer = Traner.new(params[:trainer])
if @trainer.valid?
@trainer.save
else
render 'new'
end
end
end
= form_for @trainer do |f|
class Trainer
has_many :pokeballs
has_many :pokemons, through: :pokeballs
accepts_nested_attributes_for :pokeballs, allow_destroy: true
attr_accessible :pokeballs_attributes # since Rails 4 it's done with strong params
end
class TrainersController < ApplicationController
def new
@trainer = Trainer.new
build_pokeballs
end
def create
@trainer = Traner.new(params[:trainer])
if @trainer.valid?
@trainer.save
else
build_pokeballs
render 'new'
end
end
private
def build_pokeballs
Pokemon.find_each do |pokemon|
@trainer.pokeballs.build(pokemon: pokemon) unless pokemon_already_join(pokemon)
end
end
def pokemon_already_join(pokemon)
@trainer.pokeballs.map(&:pokemon_id).include?(pokemon.id)
end
end
= form_for @trainer do |f|
= f.fields_for :pokeballs, f.object.pokeballs.sort_by(&:pokemon_id) do |f_p|
- pokemon = f_p.object.pokemon
= f_p.hidden_field :pokemon_id, value: pokemon.id
= f_p.check_box :_destroy, { checked: pokemon_checked?(@trainer, f_p.index.to_s) }, 0, 1
= f_p.label :_destroy, pokemon.name
# ugly part :s
def pokemon_checked?(trainer, form_index)
return trainer.pokemons.map(&:id).include?(pokemon.id) if @trainer.pokemons.present?
params[:trainer].present? ? destroy?(form_index) : false
end
def destroy?(form_index)
params[:trainer][:pokeballs_attributes][form_index]['_destroy'] == '0'
end
Copie de droite par MAS & VIT