【问题标题】:Rails 4 Form: has_many through: checkboxesRails 4 Form: has_many through: checkboxes
【发布时间】:2015-05-30 13:51:47
【问题描述】:

原始问题

两个资源:usersanimals. 创建用户时,客户端选中复选框来说明他们有多少动物。

当提交用户表单时,它不仅应该创建一个新的user 记录,还应该在animal_users 富连接表中创建一堆记录来代表客户端选择的每个复选框。

我认为的问题是我没有为表单中的复选框部分正确指定某些内容。我查看了checkbox_tag APIRails Guides on Forms 以及许多网站和 stackOverflow 帖子。

提前致谢,代码如下:

原始代码(答案代码再往下)

型号:

#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

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

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

此处回复代码

型号:

#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

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

中的强参数
  def user_params
    params.require(:user).permit(:name, animal_ids: [])
  end

为了完整起见,以下是表单提交时传递到服务器的内容:

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

【问题讨论】:

  • User模型中尝试使用accepts_nested_attributes_for :animal_users,看看这个帖子stackoverflow.com/questions/21983131/…
  • @Sontya 感谢您的回复。我想我越来越近了,虽然还没有到。
  • 改变你的看法&lt;% Animal.all.each do |animal| %&gt; &lt;%= f.fields_for :animal_users do |ff| %&gt; &lt;%= ff.check_box :animal_id, {}, animal.id %&gt; &lt;%= animal.name %&gt; &lt;% end %&gt;
  • @Sontya 您发布的内容很有意义。感觉就像我正在接近但仍然做错了什么。
  • 告诉我你现在卡在哪里了

标签: ruby-on-rails has-many-through


【解决方案1】:
<% Animal.all.each do |animal| %>
   <label>
      <%= check_box_tag "user[animal_ids][]", animal.id, f.object.animals.include?(animal) %>
      <%= animal.name %>
   </label>
<% end %>

你必须在你的控制器参数上接受一个带有 id 数组的散列,比如

{  animal_ids: [] }

也许阅读本文会有所帮助: http://millarian.com/programming/ruby-on-rails/quick-tip-has_many-through-checkboxes/

【讨论】:

    【解决方案2】:

    collection_check_boxes 是更好的选择:

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

    【讨论】:

    • 这非常简单和容易。 +1,谢谢!
    【解决方案3】:

    另一个使用collection_check_boxex 的例子对我来说更容易理解:

    <%= f.collection_check_boxes(:animal_ids, Animal.all, :id, :name) do |animal| %>
      <div class="form-check">
        <%= animal.check_box(class: "form-check-input") %>
        <%= animal.label(class: "form-check-label") %>
      </div>
    <% end %>
    

    它适用于 Rails 6

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-04
      • 2014-09-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      相关资源
      最近更新 更多