在Rails中创建子模型

时间:2016-06-28 17:11:39

标签: ruby-on-rails ruby ruby-on-rails-4

嗨,我有一个rails关联问题。我正在构建一个设备管理应用程序,我无法确定模型关联的设计。

因此,用户可以创建具有:make,:model,:year,:location和其他常见属性的Asset,其中包括:asset_type。资产类型可以是许多不同类型的设备,如推土机,公共汽车,发动机,挖掘机,招标等。

我曾考虑使用STI,但资产类型不共享相同的属性。我倾向于为资产模型中的每个资产类型为每个资产类型创建一个单独的模型,这个资产类型将属于资产,然后是accept_nested_pa​​rams,以便我可以使用javascript以相同的形式创建它们,以便在用户显示资产类型从选择字段中选择:asset_type。然后要访问它,我需要做类似的事情:

def show
  @asset = Asset.find(params[:id)
  @asset_type = @asset.asset_type.classify.constantize.find(params[@asset.id])
end

这对我来说是错误的。在我看来,这将是非常常见的情况,也许我只是遗漏了一些非常明显的事情。

感谢任何建议。

1 个答案:

答案 0 :(得分:0)

我认为以下代码不起作用,因为constantize实际上没有任何参数(source)。

  @asset_type = @asset.asset_type.classify.constantize(find[@asset.id])

如果您从用户输入中定义@asset.asset_type,我建议不要使用classify.constantize,因为代码注入存在漏洞。

但如果asset_type仅限于一些预先定义的值,并且每个asset_type都有相应的类,那么它应该是一种可行的方法

# in models/asset.rb   
   validates :asset_type, :inclusion=> { :in => ["bulldozer", "firetruck"] }
   def asset_type_object
     asset_type.classify.constantize.find_by(asset_id: id)
   end

# assuming Bulldozer and Firetruck classes are also defined

# in the controller
  @asset_type = @asset.asset_type_object

请注意,我还将.constantize(find[@asset.id])替换为.constantize.find_by(asset_id: id)。这是因为找到与AssetType具有相同主键的Asset没有意义。您应该使用外键进行关联。