代码之家  ›  专栏  ›  技术社区  ›  James A. Rosen

如何为Rails模型中的sti列选择输入?

  •  1
  • James A. Rosen  · 技术社区  · 15 年前

    我在上有一个具有单表继承的模型 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),但在登台服务器上失败(在RVM上为mri 1.8.7)。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Ben Sharpe    15 年前

    Ryan Bates的“Suggestion”(谁比大多数人更了解Rails)和您的实现之间的关键区别是,建议使用通过括号(“self[:type]=”)直接访问属性,而不是使用方法调用(“self.type=”)的实现。

    因此,尝试以下方法:

    class Pet < ActiveRecord::Base
      ...
      def klass
        self[:type]
      end
      def klass=(k)
        self[:type] = k
      end
    end
    
        2
  •  0
  •   Ju Nogueira    15 年前

    您还可以尝试更改与sti一起使用的列名,以获得不同于 type .

    根据 railsapi.com ,它可以在子类中设置,因此只需在 pet 模型:

    self.inheritance_column = "type_id"
    

    我只是猜测…所以我很抱歉这是完全错误的。

        3
  •  0
  •   user54697    15 年前

    如果你一定要这样做,我会在你的控制器里做一些事情:

    @pet = Pet.new(params[:pet])
    @pet[:type] = params[:pet][:type]
    

    在我看来,你最好在尝试这样做的时候既直截了当又痛苦,因为像这样快速改变类型感觉是一个非常糟糕的主意。