使用ActiveRecord :: Association方法,其中关联的“子”模型使用STI

时间:2011-04-30 21:10:25

标签: ruby-on-rails-3 activerecord sti

我有一个超级(模型)测量和两个子类:WeightMeasurement和LengthMeasurement。

然后我得到了一个Person类,其中包含尽可能多的WeightMeasurements和LengthMeasurements。

问题是在为Person创建新测量时,我想使用一个可以处理重量和长度测量的共享控制器。

然而,我通常会建立一个人的测量方法是通过父(Person)访问它们。喜欢person.weight_measurement.build。问题是我不知道该把什么放在这里......人......建造?

# Base-model, includes "type" column in database.
class Measurement < ActiveRecord::Base
    belongs_to :person
end

# model subclass
class WeightMeasurement < Measurement
end

# model subclass
class LengthMeasurement < Measurement
end


class Parent < ActiveRecord::Base
    has_many :weight_measurements, :dependent => :destroy
    has_many :length_measurements, :dependent => :destroy
end

# Single controller for "Measurements"
class MeasurementsController < ApplicationController

  ...

  def new

    person = Person.find(params[:person_id])

    # 
    normally would do this, but because I am using STI,
    # I don't know that it is a Person's "weight" measurement we are creating
    #
    # @measurement = @person.weight_measurements.build
    #

    ...

  end

...

end

1 个答案:

答案 0 :(得分:0)

我通常做的是在我的表单中创建一个隐藏字段,其中包含我要创建的类型。

<%= hidden_field_tag :type, "weight_measurement" %>

您也可以将其作为可见表单选项(例如单选按钮或选择 - 而不是上面的隐藏字段)

在您的控制器中,您可以执行以下操作:

if ["length_measurement", "weight_measurement"].include?(params[:type])
  @measurement = "Measurement::#{params[:type].classify}".constantize.new(:person => @person)
end