【问题标题】:can't get a belongs_to model to save as part of the has_one form无法将 belongs_to 模型保存为 has_one 表单的一部分
【发布时间】:2012-09-08 19:55:14
【问题描述】:

我有一个事件和活动。每个事件都有一个活动,用户需要从大量活动中进行选择。我有一个collection_select 字段可以在事件表单中正确显示,但它不会保存。我不断收到Couldn't find Activity without an ID 错误。

我认为通过在我的模型中创建 has_one belongs_to 关联,表单会自动知道要做什么。没有。所以我开始向事件控制器添加方法,甚至不知道它们是否正确。但事情并没有破裂。

现在我在想我可能需要在表单中创建一个局部变量,但我尝试了十几种变体,但没有任何效果。我只是最终收到其他错误消息。

我的事件模型

class Event < ActiveRecord::Base

  attr_accessible :date, :activity

  has_one :activity
  belongs_to :creator, :class_name => "User"
  has_many :attendees, :class_name => "User"
  has_many :comments
end

活动模型

class Activity < ActiveRecord::Base
  attr_accessible :location, :title, :image, :image_cache

  mount_uploader :image, ImageUploader

  belongs_to :event
end

事件控制器的一部分

def new
  @event = Event.new
  @activities = Activity.find(:all, :order => 'title')

end

def create
  @event = Event.new(params[:event])
  @activities = Activity.find(:all, :order => 'title')
  @activity = Activity.find(params[:id])
end

活动表单

<div class="field">
  <h6>When do you want to go?</h6><br />
  <%= f.text_field :date %>
</div>
<h5>Activities</h5>

<%= collection_select(:activity, :event_id, Activity.all, :id, :title, {:include_blank => 'Please Select'} ) %>


<div class="actions">
  <%= f.submit %>
</div>

我的无知在哪里?

【问题讨论】:

  • 您能否添加有关事件和活动表的详细信息。
  • 这条线是做什么的? @activity = Activity.find(params[:id]) 为什么你期望在 params 散列中有一个 id ?

标签: ruby-on-rails activerecord


【解决方案1】:

执行此操作时,您需要使用嵌套表单结构以便同时更新两个模型。您需要将 accepts_nested_attributes_for 添加到您的 Event model.rb 文件中。以下是您的每个文件的外观。

事件模型

class Event < ActiveRecord::Base
  attr_accessible :date, :activity

  has_one :activity
  accepts_nested_attributes_for :activity

  belongs_to :creator, :class_name => "User"
  has_many :attendees, :class_name => "User"
  has_many :comments
end

活动模型很好,因为您已经拥有 belongs_to 事件

事件控制器:

def new
  @event = Event.new
  activity = @event.activity.build
end

def create
  @event = Event.new(params[:event])
  if @event.save
    #etc.
  end
end

表格

<%= form_for @event do |f| %>  
     <div class="field">
      <h6>When do you want to go?</h6><br />
      <%= f.text_field :date %>
    </div>

    <h5>Activities</h5>
    <%= f.fields_for :activity do |b| %>
       <!--Add whatever form input you need for your activity.--> 
       <%= b.collection_select :title %>
    <% end %>

    <div class="actions">
      <%= f.submit %>
    </div>
<%end%>

如果你想好好看看结帐railscast on nested model 表格

针对 cme​​ts 中的问题...是的,我会颠倒您的模型关系设置,以便您拥有...

class Activity < ActiveRecord::Base
  has_many :events
end

class Event < ActiveRecord::Base
  belongs_to :activity
end

这样每个事件都会有一个 activity_id 列,该列将标识与其对应的活动,并用于 Rails 进行关联。

现在对于 many_to_many 关联,这听起来像是您需要的,您有两个选择。您可以使用 has_many through 或 HABTM。最简单的经验法则是,如果您认为需要将关系模型作为独立实体使用,则应该设置一个 has_many :through 关系。查看此rails guide 以获取有关这些关联将创建的所有方法的更多说明和详细信息。

我一直很喜欢 has_many,因为如果您将来选择处理这种关系,您总是可以选择处理这种关系,所以这就是您将如何做到的

class Event < ActiveRecord::Base
  has_many :plans
  has_many :users, :through => :plans
end

class Plan < ActiveRecord::Base
  belongs_to :event
  belongs_to :user
end 

class User < ActiveRecord::Base
  has_many :plans
  has_many :events, :through => :plans
end 

你可以随意称呼关系,“计划”正是我首先想到的。

【讨论】:

  • 非常感谢莫莉的详细回答。这是我接下来要尝试的方向,但我记得这更像是博客文章中的 cmets,当我查看那些我看不到的示例时,我没有看到 accept_nested_attributes。我还不明白有什么区别。
  • cmets 和博客文章的一大区别是,在大多数情况下(我假设)您不会以相同的形式/同时创建博客文章和 cmets。相反,博客是在 cmets 之前创建的,而当 cmets 稍后创建时,它是通过单独的表单创建的。在这种情况下没有嵌套表单,因此您不需要嵌套属性。
  • 实际上,我认为我没有清楚地表达我的问题。活动将以自己的形式创建。然后,在活动表单中,用户将为活动选择一个日期,然后从所有现有活动的列表中选择一项活动,然后保存该活动。用户根本不会更改事件表单中的活动字段。这有意义吗?
  • 我明白你在说什么,即使看起来你只是在“选择”一个活动,你实际上仍然在更新活动对象本身,因为你现在将它分配给事件并给予它关联的 event_id。如果您确实希望该活动属于该事件,那么您需要为该活动提供一个 event_id 列,以便它可以与一个事件相关联。但是,如果您的计划是让活动属于多个事件,那么您将需要多对多关联
  • 伙计,我以为我开始明白了。一个事件将只有一个活动(因此我认为 has_one),但一个活动可以属于任意数量的事件。 (Jimmy 想下周三去 Joe's Restaurant 吃饭。Sara 想在两周后带一个不同的团队去 Joe's Restaurant。同样的活动,不同的活动。)所以我一直认为一个活动有一个活动,一个活动属于一个活动事件。我应该像这样翻转它:一个活动 has_many events,一个 event belongs_to an activity?我突然觉得真的很无语。对不起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多