你可以在创建时传递相关模型的参数

时间:2014-08-27 07:38:23

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

我想做什么 - 我有2个模型RecordAuthor。在调用Record.create params时,我想传递相关作者模型的params。 RecordbodyAuthorname 当我尝试传递如下时 Record.create { body: "some text", author: { name: 'Some name'}}
我收到错误ActiveRecord::UnknownAttributeError: unknown attribute: author

我如何做我需要的?

更新1
协会 - 记录有作者

2 个答案:

答案 0 :(得分:2)

嵌套属性

您可能正在寻找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在此设置中的角色

请记住,您不仅仅是在这里传递单项数据 - 您正在构建&amp;传递对象。这意味着你必须考虑它们的工作原理和方法。他们的意思是什么我会给你一个简短的解释:

Rails,因为它建立在Ruby之上,是一个object-orientated框架。这意味着您在此创建/使用的每个数据都是对象。对象与变量有很大不同 - 它们更深层次和更深层次。他们拥有更多的数据,允许他们以各种不同的方式使用:

enter image description here

Rails以多种不同的方式使用对象;主要的一个是很多帮手&amp;其他方法构建自己围绕对象。这就是您在路线中获得resources指令的原因,并且可以执行以下操作:<%= link_to @user.name, @user %>

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

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

答案 1 :(得分:1)

尝试这有希望解决您的问题:

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