I am currently trying to implement a has_one relationship where you are able to search through all of blogs active posts. My problem comes where even though i explicitly search through the active_post relation it will return everything in its posts instead and not just the active ones which is what i want.
# == Schema Information
#
# Table name: blog
#
# id :integer not null, primary key
# name :string(200)
# context :string(20)
# show_on_summary :boolean
#
class Blog < ApplicationRecord
has_many :posts, dependent: :destroy, autosave: true
has_one :active_post, -> { order('created_at DESC').where(posts: { status_code: 'active' }) }, class_name: 'Post', foreign_key: :blog_id
# == Schema Information
#
# Table name: posts
#
# id :integer not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# status_code :string(20)
# blog_id :integer
#
class Post < ApplicationRecord
STATUS_CODES = %w(active pending deactivated)
belongs_to :blog
and yet when i run the code below where i have a list of posts of any type of status_code and am trying to find the blog where only their active_post relation matches, it will return every blog that has a post in that list regardless of status_code.
Blog.where(active_post: list_of_posts)
When i am debugging i can go to the individual blogs and look at their 'active_post' relation and it will show the correct latest active post. if there is no active post it will return nil which is what i want.
CodePudding user response:
I don't think you can do it without manually joining your table
Blog.joins(:active_post).where(posts: { id: list_of_posts })
When you join your table, you ensure that the relation is going to be used, and specifying the "posts"."id" column also ensures that it won't use a subquery to match the Blogs ids
CodePudding user response:
I think you don't need to specify the :posts table in the where clause:
class Blog < ApplicationRecord
has_many :posts, dependent: :destroy, autosave: true
has_one :active_post, -> { order('created_at DESC').where(status_code: 'active') }, class_name: 'Post', foreign_key: :blog_id
#...
end
Blog.first.active_post
# => return the latest post