【问题标题】:Can you pass params for associated model on create您可以在创建时传递关联模型的参数吗
【发布时间】:2014-08-27 07:38:22
【问题描述】:

我想做什么—— 我有 2 个模型 RecordAuthor。当调用Record.create params 时,我想为关联的作者模型传递参数。 Record 具有列 bodyAuthor 具有列 name 当我尝试按如下方式通过时
Record.create { body: "some text", author: { name: 'Some name'}}
我收到错误ActiveRecord::UnknownAttributeError: unknown attribute: author

我该怎么做?

更新 1
关联 - 记录有作者

【问题讨论】:

  • 这两个模型有关联吗?
  • 感谢您指出这一点。忘了说这个!
  • 没问题 - 我现在就给你写答案!

标签: ruby-on-rails activerecord ruby-on-rails-4 associations


【解决方案1】:

嵌套属性

您可能会寻找 accepts_nested_attributes_forinverse_of - 两者都依赖于您的两个模型之间的关联:

#app/models/record.rb
Class Record < ActiveRecord::Base
    has_one :author
    accepts_nested_attributes_for :author
end

#app/models/author.rb
Class Author < ActiveRecord::Base
   belongs_to :record
end

基本上,您需要构建关联数据,以便将关联属性发送到您的其他模型。我将在页面下方进一步解释这一点

如果我是你,我会这样做:

#app/controllers/records_controller.rb
Class RecordsController < ApplicationController
   def new
      @record = Record.new
      @record.author.build
   end

   def create
      @record = Record.new record_params
      @record.save
   end

   private

   def record_params
      params.require(:record).permit(:record, :attributes, author_attributes: [:name])
   end
end

#app/views/records/new.html.erb
<%= form_for @record do |f| %>
   <%= f.text_field :record %>
   <%= f.fields_for :author do |a| %>
      <%= a.text_field :name %>
   <% end %>
   <%= f.submit %>
<% end %>

这将允许您在保存时保存author 参数/属性

--

逆向

逆属性也是你的另一个想法。

我不确定它们是否会直接在这种情况下工作,但您可以使用以下方法:

#app/models/record.rb
Class Record < ActiveRecord::Base
   has_one :author, inverse_of: :author
   before_create :build_record
end

#app/models/author.rb
Class Author < ActiveRecord::Base
   belongs_to :record, inverse_of: :record
   before_create :set_options

   private

   def set_options
      self.draft = true unless self.record.draft.present?
   end
end

这意味着您应该能够在您的其他模型中访问嵌套的属性数据(我不确定在这种情况下您是否必须使用accepts_nested_attributes_for


ActiveRecord 对象

最后,您需要考虑ActiveRecord objects 在此设置中的作用

请记住,您在这里传递的不仅仅是单个数据项——您是在构造和传递对象。这意味着您必须考虑它们的工作方式以及它们的含义。我给你一个简单的解释:

Rails,因为它建立在 Ruby 之上,是一个 object-orientated 框架。这意味着您在其中创建/使用的每条数据都是一个对象。对象与变量有很大不同 - 它们更深且包含更多数据,因此可以以各种不同的方式使用它们:

Rails 以多种不同的方式使用对象;主要的一点是许多帮助器和其他方法在对象周围构建自己。这就是为什么您在路由中获得 resources 指令的原因,并且可以执行以下操作:&lt;%= link_to @user.name, @user %&gt;

许多人的问题是他们不了解 Rails 应用程序中面向对象的价值,因此尝试从脱节系统的角度思考他们的逻辑。相反,这将极大地帮助您,您需要考虑每次创建记录时,您都在构建一个对象,因此,您需要确保围绕它们构建您的应用程序。

如前所述,您必须确保在要创建的对象之间建立关联。如果这样做,您将能够同时构建它们

【讨论】:

    【解决方案2】:

    试试这个希望能解决你的问题:

    class Record < ActiveRecord::Base
        has_one :author
        accepts_nested_attributes_for :author, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
    end
    

    更多详情请见accepts_nested_attributes_for

    【讨论】:

      猜你喜欢
      • 2013-01-09
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      相关资源
      最近更新 更多