through references rails inverse_of has_one has_many has_and_belongs_to_many foreign example ruby-on-rails has-many-through

ruby-on-rails - inverse_of - rails references



Forma Rails 4: has_many through: checkboxes (2)

Pregunta original

Dos recursos: users y animals. Al crear un usuario, el cliente selecciona casillas de verificación para decir cuántos animales tiene.

Cuando se envía el formulario de usuario, no solo debe crear un nuevo registro de user , sino que también debe crear un conjunto de registros en la tabla de combinación rica animal_users para representar cada una de las casillas de verificación que el cliente seleccionó.

El problema, creo, es que no estoy especificando algo correctamente para la parte de la casilla dentro del formulario. He examinado la API checkbox_tag , las guías de Rails en formularios y muchos sitios web y publicaciones de stackOverflow.

Gracias de antemano, codifique a continuación:

Código original ( código de respuesta más abajo) :

modelos:

#models/user.rb class User < ActiveRecord::Base has_many :animals, through: :animal_users has_many :animal_users accepts_nested_attributes_for :animal_users, allow_destroy: true end #models/animal.rb class Animal < ActiveRecord::Base has_many :users, through: :animal_users has_many :animal_users end #models/animal_user.rb class AnimalUser < ActiveRecord::Base belongs_to :animal belongs_to :user end

El formulario de user :

#views/users/_form.html.erb <%= form_for(@user) do |f| %> <div class="field"> <%= f.label :name %><br> <%= f.text_field :name %> </div> <div> <% Animal.all.each do |animal| %> <label> <%= check_box_tag "user[animal_ids][]", animal.id, f.object.animals.include?(animal) %> <%= animal.animal_name %> <% end %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>

users_controller.rb fuertes dentro de users_controller.rb

def user_params params.require(:user).permit(:name, animal_users_attributes: [:_destroy, :id, :user_id, :animal_id]) end

El código de la respuesta aquí :

modelos:

#models/user.rb class User < ActiveRecord::Base has_many :animals, through: :animal_users has_many :animal_users end #models/animal.rb class Animal < ActiveRecord::Base has_many :users, through: :animal_users has_many :animal_users end #models/animal_user.rb class AnimalUser < ActiveRecord::Base belongs_to :animal belongs_to :user end

El formulario de user :

#views/users/_form.html.erb <%= form_for(@user) do |f| %> <div class="field"> <%= f.label :name %><br> <%= f.text_field :name %> </div> # Checkbox part of the form that now works! <div> <% Animal.all.each do |animal| %> <%= check_box_tag "user[animal_ids][]", animal.id, f.object.animals.include?(animal) %> <%= animal.animal_name %> <% end %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>

users_controller.rb fuertes dentro de users_controller.rb

def user_params params.require(:user).permit(:name, animal_ids: []) end

Y para completar, aquí está lo que se pasa al servidor al enviar el formulario:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"xyz=", "user"=>{"name"=>"Neil", "animal_ids"=>["1", "3"]}, "commit"=>"Create User"} Animal Load (0.2ms) SELECT "animals".* FROM "animals" WHERE "animals"."id" IN (1, 3) (0.1ms) begin transaction SQL (0.2ms) INSERT INTO "users" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", "2015-03-26 15:29:00.478767"], ["name", "Neil"], ["updated_at", "2015-03-26 15:29:00.478767"]] SQL (0.1ms) INSERT INTO "animal_users" ("animal_id", "created_at", "updated_at") VALUES (?, ?, ?) [["animal_id", 1], ["created_at", "2015-03-26 15:29:00.479833"], ["updated_at", "2015-03-26 15:29:00.479833"]] SQL (0.0ms) INSERT INTO "animal_users" ("animal_id", "created_at", "updated_at") VALUES (?, ?, ?) [["animal_id", 3], ["created_at", "2015-03-26 15:29:00.480644"], ["updated_at", "2015-03-26 15:29:00.480644"]] SQL (0.1ms) UPDATE "animal_users" SET "updated_at" = ?, "user_id" = ? WHERE "animal_users"."id" = 6 [["updated_at", "2015-03-26 15:29:00.481362"], ["user_id", 8]] SQL (0.1ms) UPDATE "animal_users" SET "updated_at" = ?, "user_id" = ? WHERE "animal_users"."id" = 7 [["updated_at", "2015-03-26 15:29:00.482062"], ["user_id", 8]] (2.4ms) commit transaction


collection_check_boxes es una mejor opción:

<%= f.collection_check_boxes(:animal_ids, Animal.all, :id, :name) do |animal| %> <%= animal.label { animal.check_box } %> <% end %>