I'm developing an application where I have several profiles, company profiles and jobs.
The company can post a job, but I can't find a way where a Profile can apply for one job.
I need to associate the job with every profile that applied to it. I guess I would have to create a column on my Job so I can list every ID that applied for that job, but I don't know how to start doing that.
Any ideas?
Thanks in advance
Assuming Profiles can apply for more than one job, you could setup your associations up like this:
class CompanyProfile
has_many :jobs, dependent: :destroy
end
class Job
belongs_to :company_profile
has_many :applications, dependent: :destroy
end
class Application
belongs_to :profile
belongs_to :job
end
class Profile
has_many :applications, dependent: :destroy
end
I think this is very much open to discussion though and it also depends what you want your app to be able to do; there might be scope for some sort of :through relationship.
Related
Using Rails 6. Here's what I want to achieve:
Shop has many reviews.
A review belongs to one Profile.
Profile has many reviews.
Profile can only have one review for a shop.
Profile cannot have more than one review for a shop.
Here's my association that is not working:
class Shop < ApplicationRecord
has_many :reviews, dependent: :destroy
end
class Profile < ApplicationRecord
belongs_to :user
has_many :reviews
end
class Review < ApplicationRecord
belongs_to :shop, counter_cache: true
belongs_to :profile, counter_cache: true
end
class User < ApplicationRecord
has_one :profile, dependent: :destroy
end
What is not working here is - as a current_user (with profile, hence current_user.profile), how do I get a shop's review of the current user? Technically should return one review.
class User < ApplicationRecord
has_one :profile, dependent: :destroy
has_many :reviews, through: :profile
end
current_user.reviews.find_by(shop: #shop)
Or
#shop.reviews.find_by(profile: current_user.profile)
This assumes you have actually added a compound index on reviews.shop_id and reviews.profile_id to ensure uniqueness.
Technically, in the code you showed, there is no limitation for a user (via a profile) to give multiple reviews for the same shop (which might also be correct/wanted, since over time their review could change?).
You seem to be looking for an "easy"/shorter way to retrieve the review(s) for a shop the current-user has given? However, since you need to find the reviews for a specific combination (of user and shop), you will always need to filter both on shop and profile.
Options:
current_shop.reviews.where(profile_id: current_user.profile_id)
Review.where(shop_id: current_shop.id, profile_id: current_user.profile_id)
current_user.profile.reviews.where(shop_id: current_shop.id)
These will all return an array of reviews. You could add .first or .last to make sure to get the review directly (if you are sure there is only one, or are only interested in the latest review for instance).
You could define a method on User to provide some kind of shorthand:
class User
def review_for(shop)
profile.reviews.where(shop_id: shop.id).last
end
end
which would return the last (most recent) review for that shop the user has made. And then you could just write
current_user.review_for(current_shop)
I currently have two Rails models as follows:
class Job < ApplicationRecord
has_many :job_interests
end
class JobInterest < ApplicationRecord
belongs_to :job
belongs_to :applicant
enum status: { pending: 0, accepted: 1, rejected: 2, cancelled: 3 }
end
I am trying to achieve that for a specific applicant (user) I can serve a list of Jobs. Each Job should be associated with one or zero JobInterest instances (for that specific user).
I've thought of multiple ways to achieve this, but all seem a bit cumbersome.
Possible solution 1:
Basically use a LEFT OUTER JOIN, e.g.
Job.includes(:job_interests).where(job_interests: { applicant_id: [current_applicant.id, nil] }).all
This results in a job list, each job having a property called job_interests which should have one item or none. One if the applicant has expressed interested, and none if the applicant hasn't done so.
Drawback: this doesn't seem like to the most straightforward approach.
Possible solution 2:
When a Job is created, automatically create JobInterests for all applicants belonging to this job. Given a lot of applications, this doesn't scale well and requires a lot of extra rows.
On the other hand, one can now get the Job list by calling
JobInterest.where(applicant_id: current_applicant.id).all
, which seems much cleaner than the previous approach.
Would you pick any of these approaches, or suggest another approach I haven't thought of.
So based on my comments in your question I think its just a simple has_many :through association. A User has many job interests and a Job has many interested Users.
class JobInterest < ApplicationRecord
belongs_to :user
belongs_to :Job
end
class User < ApplicationRecord
has_many :jobinterests, dependent: :destroy
has_many :jobs, :through => :jobinterests
end
class Job < ApplicationRecord
has_many :jobinterests, dependent: :destroy
has_many :users, :through => :jobinterests
end
This way you can simply add jobs to job interests when you view them, and remove them from the list when the user opts out of the job.
I'd like to give my users the ability to specify which Organization is their default Organization. Each user can belong to multiple Organizations, as shown below:
Class User
has_many :memberships, dependent: :destroy
has_many :organizations, through: :memberships, source: :organization
end
Class Organization
has_many :memberships, dependent: :destroy
has_many :users, through: :memberships, source: :user
end
Class Membership
belongs_to :user
belongs_to :organization
end
What would be the most appropriate way to specify that an organization and/or membership is the users default? This way, I can display the default organizations feed when they log into the application.
I've tried adding a default boolean attribute to memberships, which seems to work but just doesn't feel right. I've considered adding a default_organization attribute to the User model, which would just hold the ID of the organization, but again that doesn't seem right.
Is there a Rails approved way of handling this?
Thinking about it there are several ways you can approach this:
since this is a many to many association you can add a a field on the association model, but that needs some validation to work correctly since you can by mistake set more than one of those relations to true.
the other way is by setting a field to your user model like you described, its a little clunky but it would work.
the last way I can think, and I think is the best one is make a has_one relationship between the user and an organization. something like this:
has_one :organization, as: :default_organization
Hope it helped
Sorry for the fairly general question but I am looking to find out what would be the best way to implement a job application system in rails.
What I currently have is a user model and job model. What I would like to happen is that when a user submits an application for the job, most likely through a seperate application model, the user who posted the job will receive the application in their "applications area" and will also receive an email to the job owner's email address.
Is the best way to set this up to associate applications with users through jobs? Also would I need a seperate database table to handle the application or would it be possible to just set this up using Actionmailer?
Any help would be much appreciated! Thanks!
Sounds like a pretty straightforward has_many through association
class User < ActiveRecord::Base
has_many :applications
has_many :jobs, :through => :applications
end
class Application < ActiveRecord::Base
belongs_to :user
belongs_to :job
end
class Job < ActiveRecord::Base
has_many :applications
has_many :users, :through => :applications
end
Then in their application area you can just query user.jobs or user.applications depending on which you want to display.
New to RoR, but am having a stab at building an app - and I'm looking for some advice on my db structure.
I've got 4 models/tables: Users > Clients > Jobs > Tasks
The app will work as follows:
Users will login
They can add Clients
They can add Jobs to Clients
They can add Tasks to Jobs
So, Tasks belong to Jobs, Jobs belong to Clients, and Clients belong to Users.
I want to query the DB for any one of a Client, a Job, or a Task and also make sure that it belongs to the currently logged-in User. I'm struggling to write a 'railsy' join query and design my associations so I can do this.
I know this would be super easy if I had a user_id field in every table, but that doesn't seem like the right way to do it.
I've read the guide at http://guides.rubyonrails.org/association_basics.html, but am still in the dark a little. Can anyone shed some light on how I might structure my DB - and more importantly my associations?
Thx.
It seems you have your associations set up right from one side, all you have to do is add the other end of the associations using has_many:
class Task < ActiveRecord::Base
belongs_to :job
end
class Job < ActiveRecord::Base
belongs_to :client
has_many :tasks
end
class Client < ActiveRecord::Base
belongs_to :user
has_many :jobs
has_many :tasks, :through => :jobs
end
class User < ActiveRecord::Base
has_many :clients
has_many :jobs, :through => :clients
has_many :tasks, :through => :jobs
end
Now ActiveRecord will take care of the joins for you. It's true that in a pure db schema, you should not have the user_id in more than one place(here that would the clients table). However sometimes it would be added also to the tasks and jobs table for a performance boost, because then the db queries would not be so big. Nevertheless you have to put more effort into making your data consistent - you have to ensure that a job has the same user_id as its client for example.
Then you would be able to define shortcut associations like:
class Task < ActiveRecord::Base
belongs_to :user
end
But in this case I would not do it unless you notice the queries are too slow for your needs. Premature optimization is evil :-)
I'm not sure, if I understood your question correctly, but I believe this can be a solution:
If you write your associations like this, ActiveRecord will create automatically the joins if you ask for user.jobs or user.tasks.
class User < ActiveRecord::Base
has_many :clients
has_many :jobs, :through => :clients
has_many :tasks, :through => :jobs
end
For more Information see the Rails-Api-Documentation
If you want to get everything for a user in one request. You can do this:
user.clients.joins(:jobs => :tasks)