我有一个用户模型和角色模型,通过以下方式连接到ActiveRecord:
has_many roles, through: :role_accounts
Run Code Online (Sandbox Code Playgroud)
我希望有一个"编辑用户"屏幕,其中包含一个复选框列表,每个角色一个.使用Reform gem(v2.1.0),这是表单对象的一个片段:
class UserForm < Reform::Form
property :name
collection :roles do
property :id
end
end
Run Code Online (Sandbox Code Playgroud)
我的问题是,当提交编辑表单,并检查2个角色时,params哈希看起来像:{"user=>{"name"=>"Joe","roles"=>["2","5",""]}}我收到此错误:
[Reform] Your :populator did not return a Reform::Form instance for `roles`.
Run Code Online (Sandbox Code Playgroud)
如何为has_many设置populator?
此外,我认为我首先需要删除所有用户的角色,然后添加所选的角色,这样他们最终只能使用当前的一组角色.我怎么能用改革宝石做到这一点?
我正在使用reform-rails gem为了在我的rails项目中使用表单对象.
我意识到一个表单对象可能对我下面使用的示例代码有些过分,但它是出于演示目的.
在我创建的表单中user,与该用户记录关联的是两个user_emails.
# models/user.rb
class User < ApplicationRecord
has_many :user_emails
end
# models/user_email.rb
class UserEmail < ApplicationRecord
belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)
请注意,我没有accepts_nested_attributes_for :user_emails在User模型中使用.在我看来,表单对象的一个要点是它可以帮助你摆脱使用accepts_nested_attributes_for,所以这就是为什么我试图在没有它的情况下做到这一点.我从这个讨论重构胖模型的视频中得到了这个想法.我有链接指向表格对象上的视频部分,他表达了他不喜欢的内容accepts_nested_attributes_for.
然后我继续创建我的user_form:
# app/forms/user_form.rb
class UserForm < Reform::Form
property :name
validates :name, presence: true
collection :user_emails do
property :email_text
validates :email_text, presence: true
end
end
Run Code Online (Sandbox Code Playgroud)
因此,user_form对象包装user记录,然后包含与该user_email记录关联的几个user记录.此表单包含的记录和表单上有表单级验证 …
所以我一直在使用Traiblazer和Reform文档,我经常看到这种代码
class AlbumForm < Reform::Form
collection :songs, populate_if_empty: :populate_songs! do
property :name
end
def populate_songs!(fragment:, **)
Song.find_by(name: fragment["name"]) or Song.new
end
end
Run Code Online (Sandbox Code Playgroud)
注意def populate_songs!(fragment:, **)定义?
我很清楚双splat命名参数(比如**others)捕获所有其他关键字参数.但我从未见过**一个人,没有名字.
所以我的两个问题是: