Rails不希望存储已更改的嵌套对象属性。我用:
这里是数据库表:
create_table :accounts_roles do |t|
t.references :account, null: false
t.references :role, null: false
t.hstore :configurations
t.timestamps
end
这里的模型:
class Account < ActiveRecord::Base
has_many :accounts_roles
has_many :roles, through: :accounts_roles
accepts_nested_attributes_for :accounts_roles
end
class AccountsRole < ActiveRecord::Base
belongs_to :account
belongs_to :role
store_accessor :configurations, :color
end
控制器允许调试的所有属性:
def account_params
params.require(:account).permit!
end
在我看来,我使用fields_for:
<%= form_for @account ... %>
...
<%= f.fields_for :accounts_roles do |ar| %>
<%= ar.text_field :color ... %>
如果我提交编辑表单,参数hash看起来很好:
{"utf8"=>"✓", "account"=>{..., "accounts_roles_attributes"=>{"0"=>{"color"=>"green", "id"=>"5"}}},...}
但颜色不会变为“绿色”,它仍然是“红色”!
在rails控制台中,我尝试手动执行相同的过程:
> u = Account.first
> u.account_roles.first.color
=> "red"
> u.update(accounts_roles_attributes: { color: "green", id: 5 } )
=> true
> u.account_roles.first.color
=> "green"
> u.save
=> true
> u = Account.first
> u.account_roles.first.color
=> "red"
但没有成功。属性颜色保持“红色”。 有什么想法吗?
答案 0 :(得分:0)
解决了问题!我在模型账户上使用rolify gem。我已决定将定义的rolify关联has_and_belongs_to_many :roles
更改为has_many :accounts_roles
和has_many :roles, through: :accounts_roles
。这引发了问题,因为gem定义了gem内部的关联。因此,该模型定义了两个关联,has_and_belongs_to_many :roles
和has_many through
。钩子解决了问题(从模型帐户中删除关联has_many :accounts_roles
和has_many :roles, through: :accounts_roles
)。
# config/initializers/hook_rolify.rb
module Rolify
def rolify(options = {})
include Role
extend Dynamic if Rolify.dynamic_shortcuts
options.reverse_merge!({:role_cname => 'Role'})
self.role_cname = options[:role_cname]
self.role_table_name = self.role_cname.tableize.gsub(/\//, "_")
default_join_table = "#{self.to_s.tableize.gsub(/\//, "_")}_#{self.role_table_name}"
options.reverse_merge!({:role_join_table_name => default_join_table})
self.role_join_table_name = options[:role_join_table_name]
rolify_options = { :class_name => options[:role_cname].camelize }
# NOTE not needed any more
# rolify_options.merge!({ :join_table => self.role_join_table_name }) if Rolify.orm == "active_record"
rolify_options.merge!(options.reject{ |k,v| ![ :before_add, :after_add, :before_remove, :after_remove ].include? k.to_sym })
# NOTE defining the association has_many through
# has_and_belongs_to_many :roles, rolify_options
has_many self.role_join_table_name.to_sym
has_many :roles, rolify_options.merge!(through: self.role_join_table_name.to_sym)
self.adapter = Rolify::Adapter::Base.create("role_adapter", self.role_cname, self.name)
load_dynamic_methods if Rolify.dynamic_shortcuts
end
end