【问题标题】:Create both associated models from the form of the "belongs_to" one (rails)从“belongs_to”一个(rails)的形式创建两个关联模型
【发布时间】:2013-03-30 18:04:21
【问题描述】:

希望我连续的问题对任何人都没有问题,我想请你帮忙,如何实现一个表格创建两个模型。

两个关联的模型是

class Employee < ActiveRecord::Base
  attr_accessible :name

  belongs_to :company
  attr_accessible :company_id
end

class Company < ActiveRecord::Base
  attr_accessible :name

  has_many :employees
end

当我创建员工并且输入公司尚不存在时,我想要创建一家公司。没有“当公司不存在时”的要求,这是我的代码:

employees/_form.html.erb

<%= simple_form_for(@employee) do |f| %>
  <%= simple_form_for(@company) do |cf| %>
    <%= f.input :name, label: 'Employee Name', :required => true %>
    <%= cf.input :title, label: 'Company Name', :required => true %>
  <% end %>
<% end %>

employees_controller.rb

def new
  @employee = Employee.new
  @company = Company.new
end

[...]

def create
  @employee = Employee.new(params[:employee])
  @company = Company.new(params[:company])
  @employee.company_id = params[:company_id]

  respond_to do |format|
    if @employee.save
      format.html { redirect_to @employee, notice: 'Employee was successfully created.' }
      format.json { render json: @employee, status: :created, location: @employee }
    else
      format.html { render action: "new" }
      format.json { render json: @employee.errors, status: :unprocessable_entity }
    end
  end
end

这种员工和公司之间的某种关联(员工“持有”公司 ID)但它并没有创建(或者,如果我理解得很好,实际上并没有拯救)公司。

如果我继续在 id 分配之前添加@company.save,一切似乎都很好。然而,是吗?我不应该渲染new company form 并在提交后保存所有内容吗?

我整天都在网上搜索解决方案,但在每种情况下都以相反的方式执行:如何从新的公司形式创建一群员工。

【问题讨论】:

  • 您不能将表单放入表单中,因此我将开始重新考虑仅使用一个 simple_form_for 来呈现输入
  • “你不能”就像“这不是最佳实践”一样?因为实际显示了字段,并且发送的属性也很好。
  • 我会说它比“非最佳实践”更严重,官方 W3C XHTML 规范明确不允许这样做。它以微妙且难以检测的方式破坏浏览器!
  • 感谢您的通知,我对“盲目”遵循其他人的代码不利。作为记录,我将内部形式更改为“simple_fields_for”。 (根据问题更新)
  • 我发了一个答案,刷新一下,因为第一个版本有bug!

标签: ruby-on-rails forms rails-activerecord


【解决方案1】:

好的,经过大量的实验,我得出了这个结论:

employees/_form.html.erb

<%= simple_form_for(@employee) do |f| %>
  <%= simple_fields_for(@company) do |cf| %>
    <%= f.input :name, label: 'Employee Name', :required => true %>
    <%= cf.input :title, label: 'Company Name', :required => true %>
  <% end %>
<% end %>

employees_controller.rb

def create
  @employee = Employee.new(params[:employee])

  @company = Customer.find_or_create_by_name(params[:company][:name])
  @company.employees << @employee
  @company.save

  @employee.save
end

它比@RadBrad 提供的答案稍微优雅一些​​,但也受到它的影响。

如果您需要知道如何实际填写company 模型的所有属性,请关注this

【讨论】:

    【解决方案2】:

    有很多方法可以去,这里有一个:

    def Employee << ActiveRecord::Base
      def title
        return nil
      end
    end
    
    <%= simple_form_for(@employee) do |f| %>
      <%= f.input :name, label: 'Employee Name', :required => true %>
      <%= f.input :title, label: 'Company Name', :required => true %>
      <%= f.submit 'Create'
    <% end %>
    

    然后在您的员工控制器中:

    def create
       co = Company.find_by_title(params[:employee][:title]).first
       unless co
          co = Company.new({:company=>params[:employee][:title]})
       end
       co.employees.build({:name=>params[:employee][:name]});
       co.save
    end
    

    【讨论】:

    • employee 模型没有:title 属性,所以上面的表格给出了undefined method 'title' for Employee
    • 你的评论不清楚,我发布了一个修复程序来展示如何伪造 simple_form_for 来放置模型中不存在的属性
    • 我在您在Employee model 中添加def title 方法之前发表了评论。尽管这种方法对没有经验的我来说看起来像是“作弊”,但它完全有道理。非常感谢 - 我一测试就会接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    相关资源
    最近更新 更多