我在type
列上有一个带有单表继承的模型:
class Pet < ActiveRecord::Base
TYPES = [Dog, Cat, Hamster]
validates_presence_of :name
end
我想在新页面和编辑页面上提供<select>
下拉列表:
<% form_for @model do |f| %>
<%= f.label :name %>
<%= f.text_input :name %>
<%= f.label :type %>
<%= f.select :type, Pet::TYPES.map { |t| [t.human_name, t.to_s] } %>
<% end %>
这给了我以下错误:
ActionView::TemplateError (wrong argument type String (expected Module))
我读a suggestion使用字段#type
的别名,因为Ruby认为保留字与#class
相同。我试过了两个
class Pet < ActiveRecord::Base
...
alias_attribute :klass, :type
end
和
class Pet < ActiveRecord::Base
...
def klass
self.type
end
def klass=(k)
self.type = k
end
end
都没有奏效。有什么建议?奇怪的是,它在我的机器上工作正常(RVM上的MRI 1.8.6),但在登台服务器上失败(MRI 1.8.7不在RVM上)。
答案 0 :(得分:1)
ryan bates的“建议”(谁比大多数人更了解铁路)和你的实现之间的关键区别是建议使用通过括号直接访问属性(“self [:type] =”)与你的使用方法调用的实现(“self.type =”)
所以尝试类似:
class Pet < ActiveRecord::Base
...
def klass
self[:type]
end
def klass=(k)
self[:type] = k
end
end
答案 1 :(得分:0)
您还可以尝试将与STI一起使用的列名更改为与type
不同的内容。
根据railsapi.com
,它可以在子类中设置,因此只需在pet
模型中添加以下内容:
self.inheritance_column = "type_id"
我只是在猜...所以我很抱歉这是完全错误的。
答案 2 :(得分:0)
如果您必须这样做,我会在您的控制器中执行以下操作:
@pet = Pet.new(params[:pet])
@pet[:type] = params[:pet][:type]
IMO,你最好不要在尝试这样做时明确而痛苦,因为在飞行中改变类型就像是一个非常糟糕的想法。