Rails fields_for非嵌套模型

时间:2014-07-22 07:08:32

标签: ruby-on-rails ruby activerecord

我有一个带有以下内容的rails应用程序:

class Habit < ActiveRecord::Base
  has_many :habit_journals
  has_many :road_blocks

class RoadBlock < ActiveRecord::Base
  belongs_to :habit
  has_many :road_block_histories


class HabitJournal < ActiveRecord::Base
   belongs_to :habit
   end

我有一个创建HabitJournals的表单,虽然在这个表单中我试图创建RoadBlockHistories(这只是RoadBlock随时间的评级)

我似乎无法找到如何为此创建表单。

习惯有许多习惯日志和RoadBlocks。 RoadBlockHistories与HabitJournals没有直接关系,但我仍想在同一表格提交中捕获这些内容。

任何帮助都将不胜感激。

干杯 中号


抱歉,我意识到我需要添加其他信息。 这是Rails 4.1

用户会养成诸如“更健康”的习惯。 然后他们会为这种习惯创造一些障碍,例如“晚上吃巧克力”。和“睡觉而不是锻炼”。

当用户查看习惯时,他们可以添加日记条目(更新他们如何建立习惯)。

添加日记帐分录时,我希望用户显示所有&#34;路障&#34;用下拉菜单选择一个评级(这是他们如何使用该路障的10分中的标记)。此评级将创建road_block_history对象。

希望这可以澄清。

干杯 中号

1 个答案:

答案 0 :(得分:1)

<强>物件

我明白你想要什么 - 仍在努力考虑如何让它发挥作用。

你需要考虑的是Ruby on Rails的 nature (特别是Ruby)。 Ruby是一种object orientated语言,这意味着它所做的一切都是基于对象

您遇到的问题是您尝试创建的对象(“RoadBlockHistories”)与您尝试创建的“父”对象没有直接关联(“HabitJournals” )。


accepts_nested_attributes_for

您解决此问题的“方法”通常是使用accepts_nested_attributes_for方法 - 基本上允许您将数据从父模型传递给子模型。

这里需要注意的重要一点是,如果您的模型直接关联,则此有效,IE可以是has_manybelongs_tohas_many :through对于你想要创建的模型。

这不是魔术 - 它是核心Ruby。如果您有一个正在尝试填充的模型,如果它有关联的数据,您将能够通过原始模型发送。但是,由于语言是面向对象的,您不能只是在没有该关联的情况下填充不相关的对象


<强>修正

根据您所写的内容,我当然会将这两种形式视为单独的数据对象(IE不将它们关联起来)

也许你可以这样做(虽然它需要调整):

#app/models/habit.rb
class Habit < ActiveRecord::Base
  has_many :habit_journals
  has_many :road_blocks
end

#app/models/road_block.rb
class RoadBlock < ActiveRecord::Base
  belongs_to :habit
  has_many :road_block_histories
end

#app/models/habit_journal.rb
class HabitJournal < ActiveRecord::Base
   belongs_to :habit
   has_many :road_blocks
end

虽然这没有经过测试,但我认为它也不会起作用,我之所以包含这个原因,是为了让您了解如何将“无关联”对象传递给Rails。

您实际上可以通过其他人传递对象/数据,因此您实际上可以使用以下内容:

#app/controllers/habit_journals_controller.rb
Class HabitJournalsController < ApplicationController
   def new
       @habit_journal = HabitJournal.new
       @habit_journal.road_blocks.build.road_block_histories.build #-> again, not sure if will work
   end

   def create
       @habit_journal = HabitJournal.new(habit_journal_params)
       @habit_journal.save
   end

   private

   def habit_journal_params 
       params.require(:habit_journal).permit(:x, :y, :z, road_blocks_attributes: [road_block_histories_attributes:[] ])
   end
end

如果关联正确,则应该允许您创建以下表单:

#app/views/habit_jorunals/new.html.erb
<%= form_for @habit_journal do |f| %>
   <%= f.fields_for :road_blocks do |rb| %>
       <%= rb.fields_for :road_blocks_histories do |h| %>
           <%= h.text_field :rating %>
       <% end %>
   <% end %>
<% end %>