【问题标题】:How do I use nested attributes with the devise model如何在设计模型中使用嵌套属性
【发布时间】:2011-04-02 10:29:19
【问题描述】:

我和Creating an additional related model with Devise 有同样的问题(没有答案)。

我已覆盖用于创建新用户的设计视图并添加了公司名称,我已将模型更改为使用accepts_nested_attributes_for

没有错误,只是没有添加嵌套记录,而且我没有可以修改请求的控制器。

我有以下内容(缩短以使其可读):

routes.rb

map.devise_for :users
map.resources :users, :has_many => :companies

user.rb

has_many :companies
accepts_nested_attributes_for :companies
devise :registerable ... etc

company.rb

belongs_to :user

new.html.erb

...
<% form_for resource_name, resource, :url => registration_path(resource_name) do |f| %>
...
  <% f.fields_for :company do |company_form| %>
    <p><%= company_form.label :name %></p>
    <p><%= company_form.text_field :name %></p>
  <% end %>
...

更新: 我没有将 :company 添加到 User 模型的 attr_accessible 列表中。

【问题讨论】:

    标签: ruby-on-rails devise


    【解决方案1】:

    您可以在 User 模型中添加以下方法:

    user.rb

    def with_company
      self.companies.build
      self
    end
    

    并修改视图:

    new.html.erb

    ...
    <% form_for [resource_name, resource.with_company], :url => registration_path(resource_name) do |f| %>
    ...
      <% f.fields_for :company do |company_form| %>
      ...
      <% end %>
    

    这样,您将拥有向用户添加 one 公司的嵌套表单。 要为用户动态添加多个公司,请检查Railcast #197 by Ryan Bates。 确保您将这对资源作为数组传递,否则您将收到如下错误:“参数数量错误(3 为 2)”。

    【讨论】:

    • 我不知道这个解决方案在 MVC Modell 中的适用程度如何,但它确实有效。
    • 您应该只构建一次,否则每次提交表单时都会构建它 self.companies.build if self.companies.empty?
    • 为什么要传入resource_name,下面不应该也可以吗?
    • 对于使用此解决方案的任何人,@meleyal 和@GeorgeW 都是正确的。但是,请注意 ActiveRecord 延迟加载,使用 self.companies.build if self.companies(true).empty?,否则 empty? 可能会返回 true,即使它不应该返回。
    【解决方案2】:

    您可能正在尝试批量分配一些受保护的变量,或者您可能没有保存有效的记录。检查以确保记录实际保存到数据库中。

    【讨论】:

    • 是的 - 这是一个批量分配,我现在没有在 user.rb 的 attr_accessible 中定义 :company 新问题 - 纯粹是一个设计问题
    【解决方案3】:

    我意识到这是一个非常古老的线程,但由于我找到了更好的解决方案,因此回复了。

    只需将new.html.erb改成如下,

    <% form_for(resource, :as => resource_name,:url => registration_path(resource_name) do |f| %>
        ...
        <% prefix = "user[company_attributes]"%>
        <% fields_for prefix, @user.company do |company_form| %>
        ...
        <% end %>
    <% end %>
    

    这样,当@user.save 被调用时,它也会运行 company.save 并包含您在公司模型中可能拥有的所有验证。

    我没有大量的 RoR 经验,但我认为这是一个更好的解决方案。你怎么看?

    【讨论】:

    • 实际上,这正是fields_for :company do |company_form| 所做的。所以这不是一个更好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多