【问题标题】:What is a better way to create STI model instance什么是创建 STI 模型实例的更好方法
【发布时间】:2011-03-03 08:22:04
【问题描述】:

通常会通过其父对象构建相关模型实例:

@child = @parent.children.build(params[:child])

但是当我们使用 STI 并且我们想要这样做的同时将其构建为子类之一时,语法似乎会崩溃。据我所知,这是最好的方法(忽略不根据批准列表检查类型的安全问题):

@child = params[:type].classify.constantize.new(params[params[:type]])
@child.parent = @parent

这是最好的方法吗?我使用单个控制器来构建所有不同的子类类型,因此我需要提供类型作为参数。

【问题讨论】:

    标签: ruby-on-rails activerecord sti


    【解决方案1】:

    我通常使用这个技巧:

    class BaseModel < ActiveRecord::Base
    
    private
      # this will enable you to set the type field 
      def attributes_protected_by_default
        super - [self.class.inheritance_column]
      end
    end
    

    现在在您的控制器中:

    @parent.children.build(params[:base_model])
    

    确保 params[:base_model] 哈希有一个名为 type 的字段。我通常会添加一个隐藏的表单字段来存储类型。

    确保添加相关检查以确保创建正确的子类型。

    注意:这个技巧在 Rails 3 中不起作用。

    【讨论】:

    • 很好,我想这意味着您可以使用 AR 验证来检查该类型是否是允许的类型之一。唯一的缺点是提供的参数是 params[:child_model] 的形式,因此我事先不知道它们是什么(只有在 params[:type] 的帮助下)。我想我可以将这个参数注入到 :child_model 哈希中:)
    • 根据 apidock 的说法,此方法已移至 ActiveRecord::MassAssignmentSecurity,因此无法从模型中设置。 apidock.com/rails/ActiveModel/MassAssignmentSecurity/…
    • 这个答案特定于 Rails 2.3.x
    猜你喜欢
    • 2021-08-18
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 2015-10-27
    相关资源
    最近更新 更多