I have a technicians table, a clients table and a jobs table. My technicians model looks like this:
class Technician < ActiveRecord::Base
has_many :jobs
has_many :clients, through: :job_orders
end
My jobs model looks like this:
class Job < ActiveRecord::Base
belongs_to :technician
belongs_to :client
end
And my clients model looks like this:
class Client < ActiveRecord::Base
has_many :job_orders
has_many :technicians, through: :jobs
end
I am able to pull a list of how many jobs a technician has performed by doing
techs = Technician.all
techs.each do |tech|
puts "#{tech.name} has been assigned #{tech.jobs.count} jobs"
end
Now how can I see the technician with the fewest jobs, or the client with the most job requests? I've been thinking of sorting by sum asc/desc, but I haven't been able to wrap my mind around the issue. I am not using rails, just plain old Ruby with the activerecord gem.
Client.joins(:job_orders).order('COUNT(job_orders) DESC').group(:id).limit(1) will give you the Client with the most amount of job orders, Technician.joins(:jobs).order('COUNT(jobs) ASC').group(:id).limit(1) will give you the technicians with the fewest amount of jobs
Edit: For Rails versions < 6.0
Related
I am working in a Rails evoting app.
I have the following models: User, Election, Contestant.
I want to allow multiple users vote for contestants in a particular election, and when the user has voted in that election the links to each users should be hidden.
This association is so complicated that I can't get it right.
These are my associations:
class User < ActiveRecord::Base
has_many :contestants
has_many :contestant_votes
end
class Contestant < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
belongs_to :user
has_many :contestant_votes
has_many :elections
def votes
read_attribute(:votes) || contestant_votes.sum(:value)
end
end
class Election < ActiveRecord::Base
has_many :contestants
end
How do I hide the voting link if the current user has voted for a contestant in an election?
You can just add a uniqueness constraint on contestant_votes. Then you can add a logic to check if there is a contestant_vote between the current user and the contestant.
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.
I'm trying to figure out how to write an ActiveRecord method that will return all Boats with more than three classifications.
class Boat < ActiveRecord::Base
belongs_to :captain
has_many :boat_classifications
has_many :classifications, through: :boat_classifications
end
class Classification < ActiveRecord::Base
has_many :boat_classifications
has_many :boats, through: :boat_classifications
end
class BoatClassifications < ActiveRecord::Base
belongs_to :boat
belongs_to :classification
end
In general, I'm having trouble finding resources for writing queries on join models in AR. If anyone knows any good resources to help learn complex AR queries, that would be really helpful.
Fist JOIN the boats with the classifications. Then you need to GROUP BY boats.id so then you can COUNT how many rows you have grouped for every different boat. Using the HAVING allows you to apply that condition over the grouped records. At the end, selects the boats as you want.
Boat.joins(:classifications).group("boats.id").having("COUNT(*) > 3").select("boats.*")
I have a User that has many tasks. This is a predefined set of tasks. Each task has a list of requirements that need to be completed for the task to be finished. I have set up 2 has_many through relationships. Here is my code.
class User < ActiveRecord::Base
has_many :user_tasks
has_many :tasks, through: :user_tasks
end
class UserTask < ActiveRecord::Base
belongs_to :user
belongs_to :task
end
class Task < ActiveRecord::Base
has_many :user_tasks
has_many :users, through: :user_tasks
has_many :task_requirements
has_many :requirements, through: :task_requirements
end
class TaskRequirement < ActiveRecord::Base
belongs_to :task
belongs_to :requirement
end
class Requirement < ActiveRecord::Base
has_many :task_requirements
has_many :requirements, through: :tasks
end
This part seems fairly simple, but now I want to capture the date that each requirement is completed and a boolean of whether it is completed or not for each User. I originally tried to put it in the TaskRequirement table, but of course then it was updated for all users, which is not the behavior that I want. So I have 2 questions.
1. Where do I put these fields?
2. what is the best way to access them?
I assume they will go in a join table, but there is no easy way to access the information in the join tables.
Thanks again for all the help.
If each user completes the task requirements independently of whether other users have completed the task, then you need a UserRequirement table to store the associated data items -- the boolean and the completion date.
However, if each requirement has to be completed multiple times by each user, once for every task with which it is associated, then you'd need a join between User and TaskRequirement, or UserTask and Requirement, or User and Task and Requirement.
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