has_and_belongs_to_many 关系的自定义活动管理表单输入

2023-12-27

我有一个非常简单的模型

class Lifestyle < ActiveRecord::Base
  attr_accessible :name
  has_and_belongs_to_many :profiles
end

有一个has_and_belongs_to_many有关系Profile

class Profile < ActiveRecord::Base
  attr_accessible ...

  belongs_to :occupation

  has_and_belongs_to_many :lifestyles
  accepts_nested_attributes_for :lifestyles
end

我想使用 ActiveAdmin 编辑配置文件对象,同时也将生活方式分配给配置文件。它应该类似于处理belongs_to :occupation,因为 ActiveAdmin 会自动将其分类到一个保管箱中,其中的选项预先填充了可用职业。

我尝试过使用has_many表单生成器方法,但这只能让我显示一个表单来输入生活方式的名称,并且在提交时返回一个错误。

    f.object.lifestyles.build
    f.has_many :lifestyles do |l|
      l.input :name
    end

我得到的错误:

Can't mass-assign protected attributes: lifestyles_attributes

对我来说,完美的方法是构建几个复选框,数据库中的每种生活方式一个。选中表示生活方式与个人资料关联,未选中表示删除关系。

我非常怀疑使用 ActiveAdmin 是否可以实现这一点,而无需创建非常复杂的逻辑来处理此问题。如果您能给出您的意见并建议我是否应该走这条路或以不同的方式处理它,我将非常感激。


经过一番研究后,我准备回答我自己的问题。

首先,我必须感谢@Lichtamberg 提出的修复建议。然而,这只会使事情变得复杂(也涉及安全性,尽管在本例中不是问题),并且不能帮助我实现理想的解决方案。

深入挖掘后,我发现这是 Rails 中非常常见的场景,实际上在瑞恩·贝茨 (Ryan Bates) 的截屏视频#17 http://railscasts.com/episodes/17-habtm-checkboxes.

因此,在Rails中,如果你有一个has_and_belongs_to_many(简称HABTM)关联,你可以通过这个方法轻松设置其他关联对象的id:

profile.lifestyle_ids = [1,2]

如果您为lifestyle_ids设置了attr_accessible,这显然适用于表单:

class Profile < ActiveRecord::Base
  attr_accessible :lifestyle_ids
end

在 ActiveAdmin 中,因为它使用形式化 http://rdoc.info/github/justinfrench/formtastic,您可以使用此方法输出正确的字段(在本例中为复选框):

f.input :lifestyles, as: :check_boxes, collection: Lifestyle.all

另外,我简化了我的表单视图,所以现在只是这样:

  form do |f|
    f.inputs # Include the default inputs
    f.inputs "Lifestlyes" do # Make a panel that holds inputs for lifestyles
      f.input :lifestyles, as: :check_boxes, collection: Lifestyle.all # Use formtastic to output my collection of checkboxes
    end
    f.actions # Include the default actions
  end

好的,现在这在视图中完美呈现,但是如果我尝试提交更改,则会出现以下数据库错误:

PG::Error: ERROR:  null value in column "created_at" violates not-null constraint
: INSERT INTO "lifestyles_profiles" ("profile_id", "lifestyle_id") VALUES (2, 1) RETURNING "id"

我发现这是由于 Rails 3.2 不会自动更新 HABTM 关联表的时间戳(因为它们是额外的属性,Rails 只处理_id属性。

有 2 个解决方案可以解决此问题:

  1. 要么将关联转换为 hm:t (has_many, :through =>)
  2. 或者从表中删除时间戳

我将选择 2),因为我永远不需要时间戳或任何额外的属性。

我希望这可以帮助其他遇到同样问题的人。

Edit:@cdesrosiers 最接近解决方案,但在阅读他的答案之前我已经写了这个答案。无论如何,这还是很棒的。我学到了很多。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

has_and_belongs_to_many 关系的自定义活动管理表单输入 的相关文章

随机推荐