以下ERD包括问题中涉及的类。
以下是3个主要类(监控,链接和故事)的代码。
class Monitoring < ActiveRecord::Base
belongs_to :company
has_many :keywords, through: :monitoring_keywords
has_many :monitoring_unread_keywords, -> { order("count asc") } # database view
has_many :monitoring_keywords, dependent: :destroy
has_many :stories, through: :links
has_many :links
end
class Link < ActiveRecord::Base
belongs_to :monitoring
belongs_to :story
has_many :keyword_links
has_many :keywords, through: :keyword_links, dependent: :destroy
scope :unreads, -> { where(viewed: false) }
scope :rateds, -> { where("rating is not null") }
scope :sents, -> { where(sent: true) }
scope :discardeds, -> { where(discarded: true) }
scope :clickeds, -> { where(clicked: true) }
end
class Story < ActiveRecord::Base
has_many :keyword_links, through: :links
has_many :keywords, through: :keyword_links
has_many :links
belongs_to :source
end
我想要的是获得所有监控,包括关键字和今天的故事。以下查询返回我想要的内容,但包含所有故事。
# company_id is a column in monitorings
@monitorings = Monitoring.joins(:stories).includes([{ stories: [:source] }, :keywords]).where(company_id: current_company.id)
我不知道如何只获得今天的故事。如果我添加到where方法stories: { created_at: Date.today.beginning_of_day..Date.today.end_of_day }
,rails仍会获取所有故事,但只能获得当天至少有一个故事的监控。
我还尝试在has_many :stories, -> { where(created_at: Date.today.beginning_of_day..Date.today.end_of_day) }, class_name: "Story", foreign_key: "story_id"
之类的监控中添加网络关系,但我无法使其发挥作用。
缺少信息:监控与公司有n-1关系,监控中的company_id字段用于过滤结果。
答案 0 :(得分:1)
如果您想使用预先加载(includes
)并限制结果,Rails Docs建议您创建新关联。在这种情况下,您需要在link.rb
has_many :todays_stories, -> { where(created_at: Date.today.beginning_of_day..Date.today.end_of_day)}, class_name: "Story"
然后您可以在monitoring.rb
has_many :todays_stories, through: :links
然后你可以执行以下查询(我调整它以使用我在多租户环境中使用的格式)
@monitorings = current_company.monitorings.includes(:keywords, todays_stories: :source)
以下代码应返回您要查找的结果
@monitorings.first.todays_stories
答案 1 :(得分:1)
尝试
@monitorings = Monitoring.joins(:stories).includes([{ stories: [:source] }, :keywords]).where(company_id: current_company.id).where('stories.created_at > ? AND stories.created_at < ?', Date.today.beginning_of_day, Date.tomorrow.beginning_of_day)
答案 2 :(得分:0)
尝试:
@monitorings = Monitoring.joins(:stories).
includes([{ stories: [:source] }, :keywords]).
where(company_id: current_company.id).
where('stories.created_at > ?', Date.today.beginning_of_day)
我有时也做了一些额外的关联,它是我想要的范围。
class Monitoring < ActiveRecord::Base
belongs_to :company
has_many :keywords, through: :monitoring_keywords
has_many :monitoring_unread_keywords, -> { order("count asc") } # database view
has_many :monitoring_keywords, dependent: :destroy
has_many :stories, through: :links
has_many :new_stories, -> { where(created_at: Date.today.beginning_of_day..Date.today.end_of_day)}, through: :links
has_many :links
end
然后你可以这样做:
@monitorings = Monitoring.joins(:new_stories).
includes([{ stories: [:source] }, :keywords]).
where(company_id: current_company.id)
由于上面的答案,我遇到this article关于合并的问题,虽然我还没有测试过,但它可能完全符合您的要求。
答案 3 :(得分:0)
您可以在故事课中使用范围 例如,如果您想要故事,那么它们只会在今天创建 你可以写
default_scope - &gt; {
where(&#39; created_at&gt;?&#39;,Time.now.beginning_of_day)
}
答案 4 :(得分:0)
看起来Rails正在进行监控和故事的内部联接,这意味着您无法获得任何没有相关故事的监控记录。
解决此问题的一种方法是为joins
指定一个自定义子句,但根据Rails Guides,如果您使用includes
where
条件,它会自动发生在连接表上(这是你想要做的事情)。
tl; dr :尝试从查询中删除joins
来电:
@monitorings = Monitoring.includes([{ stories: [:source] }, :keywords]).where(company_id: current_company.id, stories: { created_at: Date.today.beginning_of_day..Date.today.end_of_day })
答案 5 :(得分:0)
我认为您应该手动编写连接查询。尝试类似的东西:
s = Monitoring.joins(
"inner join links on links.monitoring_id = monitoring.id" +
"inner join stroies on stroies.id = links.story_id"
).where("stroies.created_at = '?'", target_date).includes(:keywords)
对不起,如果我理解错了。我也可能与单数/复数不匹配