Accepts_nested_attributes_for/fields_for 不执行任何操作

发布于 2024-12-03 16:14:33 字数 4007 浏览 0 评论 0原文

我无法获取以嵌套形式给出的属性。我无法使用我的确切配置找到与此问题相关的任何其他帖子:

以下是缩写模型。正如您所看到的,用户和组织之间的关联有点复杂:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable

  attr_accessible :email, :password, :password_confirmation, :remember_me
  attr_accessible :first_name, :last_name, :nickname
  attr_accessible :current_organization_attributes

  has_many :created_organizations, :class_name => "Organization", :foreign_key => :creator_user_id, :inverse_of => :creator_user
  belongs_to :current_organization, :class_name => "Organization", :foreign_key => :current_org_id # one-way relationship

  accepts_nested_attributes_for :current_organization
  ...
end

class Organization < ActiveRecord::Base
  belongs_to :creator_user, :class_name => "User", :foreign_key => "creator_user_id", :inverse_of => :created_organizations
  ...
end

缩写模式:

# == Schema Information
#
# Table name: users
#
#  id                   :integer(4)      not null, primary key
#  email                :string(255)     default(""), not null
#  current_org_id       :integer(4)
#  first_name           :string(255)
#  last_name            :string(255)
#  nickname             :string(255)
#

# == Schema Information
#
# Table name: organizations
#
#  id                      :integer(4)      not null, primary key
#  name                    :string(100)
#  creator_user_id         :integer(4)      not null
#  zip_code                :string(255)
#  phone_number            :string(255)
#

这是缩写视图代码 (HAML):

#main
  %h1 Your account
  = form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :autocomplete => "off" }) do |f|
    = devise_error_messages!
    .edit-account-hold
      %span About you
      = f.label :first_name, "First Name"
      = f.text_field :first_name, :required => @contact_request_is_pending
      ...

    .edit-account-hold
      %span Your business
      = f.fields_for :current_organization do |o|
        = o.label :zip_code, "Zip Code"
        = o.text_field :zip_code, :required => @contact_request_is_pending
        = o.label :phone_number, "Phone Number"
        = o.text_field :phone_number, :required => @contact_request_is_pending

    .edit-account-hold
      %span Your password
      = f.label :password
      = f.password_field :password
      = f.label :password_confirmation
      = f.password_field :password_confirmation
      = f.label :current_password
      = f.password_field :current_password

      = f.submit "Update", :class => "orange-button border-radius"

控制器代码:

def update
  if resource.update_with_or_without_password_as_needed(params[resource_name])
    set_flash_message :notice, :updated
    redirect_to after_update_path_for(resource)
  else
    clean_up_passwords(resource)
    render_with_scope :edit
  end
end

这是单击“更新”时传递的参数示例:

{"utf8"=>"✓", "authenticity_token"=>"8aL7bMJdVI2uaLt3WoZEraSB0U5iZgBvxYh5fwsQnqM=", "user"=>{"first_name"=>"Nick", "last_name"=>"", "nickname"=>"", "email"=>"[email protected]", "current_organization_attributes"=>{"zip_code"=>"12345", "phone_number"=>"1112223333", "id"=>"1000003"}, "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "current_password"=>"[FILTERED]"}, "commit"=>"Update"}

嵌套哈希 params["user"]["current_organization_attributes"] 包含无法保存的属性。使用服务器内的调试器,我已经确认在适当的时间进行调用

user.current_organization.update_attributes( the_above_mentioned_current_organization_attributes_hash )

效果很好,并且就像我想要的那样更新属性。为什么系统不自动执行此操作?这与使用备用类名或外键的belongs_to关系有关吗?

帮助!

I cannot get the attributes given in a nested form to take. I haven't been able to find any other posts related to this issue with my exact configuration:

Here are the abbreviated models. As you can see, the associations between Users and Organizations are a bit complex:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable

  attr_accessible :email, :password, :password_confirmation, :remember_me
  attr_accessible :first_name, :last_name, :nickname
  attr_accessible :current_organization_attributes

  has_many :created_organizations, :class_name => "Organization", :foreign_key => :creator_user_id, :inverse_of => :creator_user
  belongs_to :current_organization, :class_name => "Organization", :foreign_key => :current_org_id # one-way relationship

  accepts_nested_attributes_for :current_organization
  ...
end

class Organization < ActiveRecord::Base
  belongs_to :creator_user, :class_name => "User", :foreign_key => "creator_user_id", :inverse_of => :created_organizations
  ...
end

And abbreviated schemas:

# == Schema Information
#
# Table name: users
#
#  id                   :integer(4)      not null, primary key
#  email                :string(255)     default(""), not null
#  current_org_id       :integer(4)
#  first_name           :string(255)
#  last_name            :string(255)
#  nickname             :string(255)
#

# == Schema Information
#
# Table name: organizations
#
#  id                      :integer(4)      not null, primary key
#  name                    :string(100)
#  creator_user_id         :integer(4)      not null
#  zip_code                :string(255)
#  phone_number            :string(255)
#

Here is the abbreviated view code (HAML):

#main
  %h1 Your account
  = form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :autocomplete => "off" }) do |f|
    = devise_error_messages!
    .edit-account-hold
      %span About you
      = f.label :first_name, "First Name"
      = f.text_field :first_name, :required => @contact_request_is_pending
      ...

    .edit-account-hold
      %span Your business
      = f.fields_for :current_organization do |o|
        = o.label :zip_code, "Zip Code"
        = o.text_field :zip_code, :required => @contact_request_is_pending
        = o.label :phone_number, "Phone Number"
        = o.text_field :phone_number, :required => @contact_request_is_pending

    .edit-account-hold
      %span Your password
      = f.label :password
      = f.password_field :password
      = f.label :password_confirmation
      = f.password_field :password_confirmation
      = f.label :current_password
      = f.password_field :current_password

      = f.submit "Update", :class => "orange-button border-radius"

Controller code:

def update
  if resource.update_with_or_without_password_as_needed(params[resource_name])
    set_flash_message :notice, :updated
    redirect_to after_update_path_for(resource)
  else
    clean_up_passwords(resource)
    render_with_scope :edit
  end
end

Here is a sample of the params that are passed when "Update" is clicked:

{"utf8"=>"✓", "authenticity_token"=>"8aL7bMJdVI2uaLt3WoZEraSB0U5iZgBvxYh5fwsQnqM=", "user"=>{"first_name"=>"Nick", "last_name"=>"", "nickname"=>"", "email"=>"[email protected]", "current_organization_attributes"=>{"zip_code"=>"12345", "phone_number"=>"1112223333", "id"=>"1000003"}, "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "current_password"=>"[FILTERED]"}, "commit"=>"Update"}

The nested hash params["user"]["current_organization_attributes"] contains the attributes that are failing to save. Using the debugger within the server, I have confirmed that a call to

user.current_organization.update_attributes( the_above_mentioned_current_organization_attributes_hash )

at the appropriate time works great and updates the attributes just like I'd like. Why won't the system do this automatically? Is it something to do with the belongs_to relationship using alternate class names or foreign keys?

Help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故乡的云 2024-12-10 16:14:33

IIRC,accepts_nested_attributes_for 仅适用于 has_onehas_many 关联……至少,粗略浏览一下文档就会发现这一点。我认为它不适用于 belongs_to

我最好的建议是更改用户模型中的关联(这也需要架构更改)以执行以下操作:

has_many :organizations
has_one :current_organization, :class_name => "Organization", :conditions => {:current => true}

其中 organizations 表有一个名为 current 的列,并验证只有一个组织可以是当前组织,如果该列已更新(范围仅限于该列),则可能会使用回调将该用户组织的所有其他当前值更改为 false用户,显然)。

这应该允许 fields_foraccepts_nested_attributes_for 按预期工作。

IIRC, accepts_nested_attributes_for only works for has_one or has_many associations... at least, that's what a cursory glance at the docs reveals. I don't think it works on belongs_to.

My best suggestion is to change the association in the User model (and this requires schema changes as well) to do something like:

has_many :organizations
has_one :current_organization, :class_name => "Organization", :conditions => {:current => true}

Where the organizations table has a column called current, and validate that only one organization can be current, maybe with a callback that changes all other current values for that users' organizations to false if the column is updated (scoped to that user, obviously).

This should allow fields_for and accepts_nested_attributes_for to work as intended.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文