【问题标题】:RoR multi nesting with polymorphic associations + devise具有多态关联的 RoR 多嵌套 + 设计
【发布时间】:2015-03-05 00:19:26
【问题描述】:

我有不同模型的多态关联,我想在使用 devise 提交注册表时保存这些关联。 IE: 用户 公司+联系方式 员工 + 联系方式

我知道不建议使用嵌套表单,但是实现这一点的最佳方法是什么?

谢谢

型号:

class User < ActiveRecord::Base
  belongs_to :company
  accepts_nested_attributes_for :company
end

class Company < ActiveRecord::Base
  has_many :employees
  has_one :contact_info, as: :contactable
  accepts_nested_attributes_for :contact_info
end

class Employee < ActiveRecord::Base
  belongs_to :company
  has_one :contact_info, as: :contactable
  accepts_nested_attributes_for :contact_info
end

class ContactInfo < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
end

迁移:

class CreateCompanies < ActiveRecord::Migration
  def change
    create_table :companies do |t|
      t.string :name
      t.references :contact_info, index: true
      t.string :website
      t.timestamps null: false
    end
    add_foreign_key :companies, :contact_infos
  end
end

class CreateEmployees < ActiveRecord::Migration
  def change
    create_table :employees do |t|
      t.string :first_name
      t.string :last_name
      t.references :company, index: true
      t.references :contact_info, index: true
      t.string :job_title
      t.timestamps null: false
    end
    add_foreign_key :employees, :contact_infos
  end
end

class CreateContactInfos < ActiveRecord::Migration
  def change
    create_table :contact_infos do |t|
      t.string :email
      t.string :phone
      t.string :mobile
      t.string :contactable_type
      t.integer :contactable_id

      t.timestamps null: false
    end
  end
end

注册控制器:

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up).push(:name, :email, :password, company_attributes: [ :id, :name, :website, :company_type, :number_of_employees, contact_info_attributes: [ :id, :email, :phone, :mobile]])
  end

设计的新注册:

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :role => 'form'}) do |f| %>
    <%= devise_error_messages! %>

    <%= hidden_field_tag 'plan', params[:plan] %>

    <% resource.build_company %>
    <%= f.fields_for :company do |f| %>
      <%= render "companies/fields", f: f %>
    <% end %>

    <% resource.company.build_contact_info %>
    <%= f.fields_for :contact_info do |f| %>
      <%= render "contact_infos/fields", f: f %>
    <% end %>

    <div class="form-group">
      <%= f.label :name %>
      <%= f.text_field :name, :autofocus => true, class: 'form-control' %>
    </div>
    <div class="form-group">
      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>
    </div>
    <div class="form-group">
      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>
    </div>
    <div class="form-group">
      <%= f.label :password_confirmation %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>
    </div>
     <%= f.submit 'Sign up', :class => 'button right' %>
<% end %>

控制台:

  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Nb6Na8P93s1dYvlDIQuiG11IoDeSzSylH4BCN8Tm7ipxCsbsdiWjDx5tJpijwldkjK4pPfjuwROnEvybYS7UIQ==", "plan"=>"free", "user"=>{"company_attributes"=>{"name"=>"Company Name", "website"=>"company website", "company_type"=>"company type", "number_of_employees"=>"121"}, "contact_info"=>{"email"=>"company@email.com", "phone"=>"1234", "mobile"=>"1234"}, "name"=>"user_name", "email"=>"user_email@email.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
Unpermitted parameter: contact_info

只有用户和公司参数保存得很好。我试图让 devise_parameter_sanitizer 首先在公司中使用嵌套的contact_info,而不是对员工进行同样的尝试,知道我做错了什么或者如果我走在正确的轨道上有任何提示吗?

谢谢!

更新:

但是,如果我将contact_info 表单字段嵌套在公司表单字段中,则允许使用contact_info 参数,如下所示:

<% resource.build_company %>
<%= f.fields_for :company do |f| %>
  <%= render "companies/fields", f: f %>
  <% resource.company.build_contact_info %>
  <%= f.fields_for :contact_info do |cf| %>
    <%= render "contact_infos/fields", f: cf %>
  <% end %>
<% end %>

问题是,这是好的做法吗?

【问题讨论】:

  • 您能否扩展“储蓄得很好”(或者说真的,什么事情做得不好)您到底观察到哪些事情不起作用?你有错误吗?您能否向我们展示相关日志以尝试保存? (有时这是一个许可/要求问题,日志会告诉你什么是不允许的。有时你会看到参数通过的不是你所期望的)
  • @TarynEast 是的,你完全正确,我的错。我已将控制台中的参数添加到问题中。谢谢!
  • 我认为问题是我在用户模型中没有accepts_nested_attributes_for :contact_info,这当然行不通,因为我们之间没有关系。
  • 是的,您已将表单设置为直接将联系信息输入用户,但您需要先将联系信息输入公司(例如)。也许你需要一个fields_for :company 并在里面放你的fields_for :contact_info
  • 好的,我添加了一个合理的解决方案 - 看起来您的嵌套联系信息实际上并没有嵌套在公司内部,什么时候应该......试试这个,看看它是否有效?

标签: ruby-on-rails devise nested-attributes polymorphic-associations


【解决方案1】:

这是一个猜测 - 但您的公司联系人信息并未嵌套在公司部分中。尝试这样的事情(注意,未经测试,可能有问题)

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :role => 'form'}) do |f| %>
<%= devise_error_messages! %>

<%= hidden_field_tag 'plan', params[:plan] %>

<% resource.build_company %>
<%= f.fields_for :company do |f| %>
  <%= render "companies/fields", f: f %>

  <%# this is now nested inside the company-fields %>
  <% resource.company.build_contact_info %>
  <%= f.fields_for :contact_info do |f| %>
    <%= render "contact_infos/fields", f: f %>
  <% end %>

<% end %>

<div class="form-group">
  <%= f.label :name %>
  <%= f.text_field :name, :autofocus => true, class: 'form-control' %>
</div>
<div class="form-group">
  <%= f.label :email %>
  <%= f.email_field :email, class: 'form-control' %>
</div>
<div class="form-group">
  <%= f.label :password %>
  <%= f.password_field :password, class: 'form-control' %>
</div>
<div class="form-group">
  <%= f.label :password_confirmation %>
  <%= f.password_field :password_confirmation, class: 'form-control' %>
</div>
 <%= f.submit 'Sign up', :class => 'button right' %>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    相关资源
    最近更新 更多