Reputation: 806
I have a Kid model that belongs to a Mom and a Dad.
class Kid
belongs_to :mom
belongs_to :dad
end
class Mom
has_many :kids
has_many :dads, through: :kids
end
class Dad
has_many :kids
has_many :moms, through: :kids
end
Now what I'm doing is listing a Dad's kids based on when it was created, age and distance from the Mom.
def show
@dad = Dad.find(params[:id])
near = Mom.near(@user_location, 100, :select => "kids.*") # Geocoder gem
@kids = @dad.kids.joins(:mom).merge(near).order(age: :asc, created_at: :desc).page(params[:page])
end
I have a boolean field on the Mom model called is_online
. I want this field to make it so results won't be based on the near
method or distance and the the online moms will be in front. So, the results of the pagination would look like:
online kid, 2 years old
online kid, 3 years old
offline kid, 4 years old, 4 miles away
offline kid, 5 years old, 5 miles away
My problem is, I don't know how to make my Kid be just one scope so I don't have to make @online_kids
and @offline_kids
. I just want to keep it as @kids
. Any suggestions?
Upvotes: 0
Views: 154
Reputation: 51151
So you have to use order
clause, I guess:
@kids = @dad.kids.joins(:mom).merge(mom).order('moms.is_online DESC, kids.age ASC, kids.created_at DESC').page(params[:page])
You build your Mom
query this way, basing on other answer:
near = Mom.near(@user_location, 100, :select => "kids.*").where(is_online: false).where_values.reduce(:and)
online = Mom.where(is_online: true).where_values.reduce(:and)
mom = Mom.where(near.or(online))
Upvotes: 2
Reputation: 73589
You can create different scope for online and offline, like this:
class Kid
belongs_to :mom
belongs_to :dad
scope :online, lambda { where(:is_online => true) }
scope :offline, lambda { where(:is_online => false) }
end
Now, You can further filter search results by these scope.
For example
kids = Kid.where(:age > 2)
kids.online # these will be online kids
kids.offline # these will be offline kids
Upvotes: 0