Ruby on rails 为Rails中的所有关联重新定义外键名称
我有一个STI模型,它有许多关联:Ruby on rails 为Rails中的所有关联重新定义外键名称,ruby-on-rails,ruby,activerecord,foreign-keys,sti,Ruby On Rails,Ruby,Activerecord,Foreign Keys,Sti,我有一个STI模型,它有许多关联: class MyModel < ActiveRecord::base has_many :things has_many :other_things # ... a lot of `has_many` end 但是我的联想不起作用。它们有MyModel\u id列,因为它们引用的是MyModel,它们也应该引用Nested。但是所有这些都有许多希望使用嵌套的\u id列作为外键(这取决于类名) 我本可以在类嵌套中键入: has_many :
class MyModel < ActiveRecord::base
has_many :things
has_many :other_things
# ... a lot of `has_many`
end
但是我的联想不起作用。它们有MyModel\u id
列,因为它们引用的是MyModel
,它们也应该引用Nested
。但是所有这些都有许多希望使用嵌套的\u id
列作为外键(这取决于类名)
我本可以在类嵌套中键入:
has_many :things, foreign_key: 'my_model_id'
has_many :other_things, foreign_key: 'my_model_id'
但是如果可能的话,如何在嵌套的类中同时指定所有关联的外键
?如果所有的都有很多的关联在MyModel
上声明,你应该很好,否则你可能会从升级Rails中获益;在4.2.4中,以下内容非常适合我。Rails使用声明has\u many
的类来生成外键
,因此即使嵌套
继承时,:仍会通过我的模型id
来查找内容
class MyModel < ActiveRecord::Base
has_many :things
end
class MyA < MyModel
end
class Nested < MyModel
self.inheritance_column = nil
end
class Thing < ActiveRecord::Base
belongs_to :my_model
end
:
所以最简单的方法就是循环:
class Nested < MyModel
self.inheritance_column = nil
%i[things other_things].each do |association|
has_many association, foreign_key: 'my_model_id'
end
end
我的解决方案可能不被推荐,但它是有效的。这是:
class Nested < MyModel
def self.name
MyModel.name
end
end
类嵌套
ActiveRecord
将为Nested
和MyModel
类中定义或重新定义的所有关联查找MyModel\id
外键。继承用于专门化,子类应该可以在其超类所在的任何位置使用。如果Nested
不是STI,则它不应继承自已存在的内容。如果您陈述了创建嵌套的的实际目标,也许我们可以帮助您进行设计。@Kristján,不,这不是设计问题,我也知道继承和STI的目的。但是,当环境超过常规时,编程中有许多不同的情况。这个例子百分之百符合我的需要。问题只是一次重新定义所有外键这一切都是一个设计问题:)好吧,它可能在Rails中本身。好吧,我所做的正是“不可取的重写Nested.name
”如果smb知道这种方法的缺点,请告诉我
def derive_foreign_key
if belongs_to?
"#{name}_id"
elsif options[:as]
"#{options[:as]}_id"
else
active_record.name.foreign_key
end
end
class Nested < MyModel
self.inheritance_column = nil
%i[things other_things].each do |association|
has_many association, foreign_key: 'my_model_id'
end
end
class Nested < MyModel
self.inheritance_column = nil
def self.has_many(klass, options={})
options.reverse_merge!(foreign_key: 'my_model_id')
super
end
has_many :things
has_many :other_things
end
class Nested < MyModel
def self.name
MyModel.name
end
end