Rails 3 scope with multiple models - ruby

Here are my models:
Patient:
has_many :patient_records
PatientRecord:
belongs_to :patient
has_many :progress_reports
ProgressReport:
has_one :patient_record
The query I am trying to produce is to get all patients where progress_reports are older than or equal to 7 days from now (using a date_of_report column in progress_reports) while including or joining the patient record table... I have been working on this for so long that I have ran into a brick wall.

I would try:
scope :recent_patients, lambda
{ |since_when| join(:progress_reports)
.where("progress_reports.created_at >= ?", since_when)}
in your Patient model

reports = ProgressReport.where(:created_at > 7.days.ago).all
if you want to get each patient that belongs to each record, do:
reports.each do |r|
puts r.patient.name
end

Related

Setting up a many-to-many relationship in Active Record

I have two models: meal_plans and dinners. Each meal_plan will have a week's worth of dinners, and each dinner will be on, potentially, several meal_plans.
I'm wondering what the best approach is to save 7 dinner IDs into a meal plan. Initially, I was just going to save an array of dinner IDs into a meal plan's params with a helper:
def create_week_of_meals(week)
ids = []
week.each {|dinner| ids.push(dinner.id)}
return ids
end
With strong params:
params.require(:meal_plan).permit(:user_id, :meals)
This works alright, but it leaves me with a string of meal_ids which I would have to turn back into an array and then query Dinners for each one of those dinner ids. Is there a better way of doing this? I've seen a lot of references to rails accepts_nested_attributes_for but from what I can tell that mostly deals with saving some attributes from another model into the current record, whereas I'm looking to save a reference to several models.
I am familiar with has_many_through relationships but it seems like a lot of overhead to create a separate model and seven new records for each meal plan just to attach some dinner_ids to a record.
class Dinner < ActiveRecord::Base
has_many :meal_plan_placements
has_many :meal_plans, through: :meal_plan_placements
end
class MealPlan < ActiveRecord::Base
has_many :meal_plan_placements
has_many :dinners, through: :meal_plan_placements
end
class MealPlanPlacement < ActiveRecord::Base
belongs_to :dinner
belongs_to :meal_plan
end
This should work, but I haven't actually run it locally, so you should play around with it. You can also read more about the through option.

How to load parent-child-parent associations in Rails 4?

this is my first question on StackOverflow :)
I'm building a Rails 4 app, having trouble to figure out a good way to load records from mutilple data models. I could hard code SQL statements like an inner join, but wondering if there's any better way. Searched in existing questions on SO, but didn't find a match.
Here are my models:
class Person < ActiveRecord::Base
has_many :addresses
end
class Address < ActiveRecord::Base
belongs_to :person
belongs_to :city
end
class City < ActiveRecord::Base
has_many :addresses
end
Question: given a person Id, how should I load its associated addresses with the city information?
Address.includes(:persons,:cities).where(person_id: person.id)
this is one of many ways.

How to check if model has existing model associations in Rails?

I have two ActiveRecord models (Book, Ad) which are associated. In my query I want to fetch books which has got 1 or more ads. What would be the best way to do this?
# in controller:
#books = Book.where(book has got 1 or more ads).last(20)
# Book model:
class Book < ActiveRecord::Base
has_many :ads, :dependent => :destroy
...
end
# Ad model:
class Ad < ActiveRecord::Base
belongs_to :book
...
end
One option is to use joins:
Book.joins(:ads)
joins allows you to do all of this in one query, and this would give you all Books that have a book_id on Ad set.
So for your controller, you'd have:
#books = Book.joins(:ads).last(20)
in your controller
subquery = Ad.select("book_id").group(:book_id).having("COUNT(*) >= 1").to_sql
#books = Book.where("id IN (#{subquery})").last(20)
Another simple solution would be
Ad.all.map{|ad| ad.book}.uniq.last(20)
This will return the last 20 unique books in an Array because if a Ad exists then it has a Book thus the Book has 1 or more Ads

Multiple Has Many Through One Relationships Pointing to Same Models - Getting data out in ruby

I have two separate has many through one relationships pointing to the same objects.
Users have many photos through photo_relationships
Users have many photos through votes
In my controller I'm trying to show all of the photos for the user through this code:
#user = User.find(params[:id])
#photos = #user.photos
However, the Inner Join is being controlled by whatever has_many relationships is mentioned last in the User model, in this case votes. Is there a way to specify what inner join is used such as:
#photos = #user.photos( joins: :photo_relationships)
Do something like this:
class User
...
has_many :voted_photos, class_name: 'Photo', through: :votes
has_many :relationship_photos, class_name: 'Photo', through: :photo_relationships
end

Ruby on Rails 3: How can I sort ActiveRecords by an attribute of another table?

I need to query a database table and get the rows ordered by a count of an association. Is there a Rails (like Active Record Query) way to do this?
My models and their associations are as follows:
class User < ActiveRecord::Base
has_one :business
end
class Business < ActiveRecord::Base
has_many :postulations
end
class Postulation < ActiveRecord::Base
belongs_to :business
end
I need to get a number of Users ordered by the amount of Postulations that their Business has. Is there a clean way to do this or do I just have to query with find_by_sql?
Thank you.
User.includes(:business => :postulations).group("users.id").order("count(postulations.id) desc").limit(20)
This will probably work

Resources