在Rails 4应用程序中,我有一个STI模型,它将元数据存储在jsonb列中。
基类:
class Post < ActiveRecord::Base
...
end
子类:
class JobPost < Post
# has a jsonb column for metadata
end
JobPost的元数据列中的一个数据属性是对另一个表(company_id
)的foreign_key引用。我想在JobPost模型中添加belongs_to :company
引用。这似乎应该可以通过做
class JobPost < Post
belongs_to :company do
Company.find_by_id self.metadata['company_id']
end
end
但这似乎不起作用。帮助
注意:我不一定打算使用belongs_to
而不是手动编写def company
所需的方法,但我确实需要一种方法来在列出职位时急切加载公司。如果有一种方法可以在没有belongs_to
关系的情况下进行那种热切的加载,我就会全力以赴。
UPDATE1
我也尝试了以下内容,但似乎无效:
class JobPost < Post
belongs_to :company, foreign_key: "(posts.metadata->>'company_id')::integer".to_sym
end
UPDATE2
更清楚我的意图和需要:
1)一个公司的JobPost belongs_to
,但是Post(和Post的其他子类)没有。当其他子类不使用时,我宁愿不要将company_id
列添加到posts
表中。
2)JobPost可以证明拥有自己的桌子(也许与公司的关系足以证明它的合理性)。有理由说这不是理想的,但如果这是唯一的答案,我会接受它。然而,在走上这条道路之前,我会更喜欢一个更明确的“你要做的事情无法做到”的回应。
主要问题是您是否可以自定义belongs_to
以便它使用元数据列而不是期望外键成为表中的列。
第二个问题是,在没有建立belongs_to
关系的情况下,您是否可以将公司加入公司和工作岗位。
答案 0 :(得分:1)
修改强>
UPD 2
您需要添加&#34; company_id&#34;列到STI表的基类。如果JobPost继承自Post,它应该有&#34; company_id&#34;然后添加&#34; company_id&#34;列到帖子(基表)。
记住STI代表&#34;单表继承&#34;所以在数据库模式级别上只有一个表。想象一下Post表的一列,其中很少有数据记录是具有company_id的公司的外键条目,以及具有非JobPost子类类型的该列的其他记录,它们是空/空吗?因此,关系是使用父STI表定义的,子类继承了这些关系。 STI中的附加类型列定义子类类型。
检查here
如果JobPost和Post都与公司有关系,您可能需要进一步挖掘Polymorphic classes而不是STI,否则创建两个单独的模型,因为它们往往有一些独特的关系和列字段。
<强> UPD 强>
基于更新的问题
class Company < ActiveRecord::Base
has_many :posts
delegate :jobposts, to: :posts
end
&#13;
class Post < ActiveRecord::Base
belongs_to :company
self.inheritance_column = :ptype
scope :job_posts, -> { where(ptype: 'JobPost') }
def self.ptype
%w(JobPost)
end
end
&#13;
class JobPost < Post; end
&#13;
company = Company.create!(company_params)
&#13;
company.posts << JobPost.new(jobpost_params)
&#13;
company.job_posts
&#13;
如果你将jonb中的company_id存储在任何哪一列中,只需相应地格式化你的jobpost_params哈希输入,它应该为你做契约
OLD ASK
按主键查找
Company.find(id)
在您的情况下,ID为self.metadata [&#39; company_id&#39;]
通过其他键找到
Company.find_by(key: value)
不再推荐使用Company.find_by_id
请删除你的模型中的belongs_to之后的do和end,而不是在你的控制器中你可以写:
Jobpost.all.each do |x|
# your do
end
关于外键,因为rails是约定优于配置,它默认包含对Jobpost的company_id引用,您可以在Company.rb模型中更改