I have the follow model setup:
class Favorite < ActiveRecord::Base
belongs_to :favoritable, :polymorphic => true
belongs_to :user
end
class Photo < ActiveRecord::Base
belongs_to :user
has_many :favorites, :as => :favoritable
end
class User < ActiveRecord::Base
has_many :photos
end
And that Favorite model has favoritable_id and favoritable_type` fields.
What I ultimately want to do is check and see if a User has already marked a photo as a favorite.
I'm able to create the database record without issue...it's the checking to see if that user already has favorited the photo (or other data type) that I'm having issues with.
I could obviously do some sort of raw SQL query to get it, but seems like there's gotta be a more "standard" way of doing it.
I'm running Rails 3.0.3.
you can add two other associations in the User model and a method that checks if the photo is favorite :
has_many :favorites
has_many :favorites_photos, :through => :favorites, :source => :favoritable, :source_type => 'Photo'
def photo_favorite?(photo)
favorites_photos.exists?(photo.id)
end
or more simply just by adding this method to the Photo model :
def favorite_for?(user)
favorites.exists?(:user_id => user.id)
end
I did not tested it, but I think it should work.
Related
I have a polymorphic association like so (adapted from guides.rubyonrails.com):
class Picture < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
end
class Employee < ActiveRecord::Base
has_many :pictures, :as => :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, :as => :imageable
has_many :employees
end
Is there a way to get all of the possible :imageable_types only given the Picture model?
For example to get the class of has_many :quotes in the Product model, you would do:
Product.reflect_on_association(:employees).klass
to get: # => Employee
Now I want to do something similar:
Picture.reflect_on_association(:imageable).klass
This obviously throws an exception, but I want to get something like: # => [Employee, Product]
Is there a way to do this? (Without trying out all models to see if they contain has_many :pictures)
I couldn't find a way to do this without looking at all the models, so I just adapted this solution: https://stackoverflow.com/a/2315469/1440599
I've got the following models and associations:
class User < ActiveRecord::Base
has_and_belongs_to_many :songs
end
class Song < ActiveRecord::Base
has_and_belongs_to_many :users
belongs_to :album
delegate :artist, :to => :album, :allow_nil => true
end
class Album < ActiveRecord::Base
has_many :songs
belongs_to :artist
end
class Artist < ActiveRecord::Base
has_many :albums
has_many :songs, :through => :albums
end
I need to be able to call user.albums and user.artists on a regular basis. Is the most efficient option to create has_and_belongs_to_many associations between User and Artist/Album ?
It seems like there should be a better way but I haven't been able to find anything yet.
You could just use has_many :albums, :through => :songs on the user object. Arel(AR) will automatically create the joins for you resulting in one query and will only fetch the albums related to the songs belonging to the User. The same goes for the artists on the User object.
First I'm using Rails 3.1 from the 3-1-stable branch updated an hour ago.
I'm developing an application where I have 3 essential models User, Company and Job, Here's the relevant part of the models:
class User < ActiveRecord::Base
has_many :companies_users, class_name: "CompaniesUsers"
has_many :companies, :through => :companies_users, :source => :company
end
class Company < ActiveRecord::Base
has_many :companies_users, class_name: "CompaniesUsers"
has_many :employees, :through => :companies_users, :source => :user
has_many :jobs, :dependent => :destroy
end
class Job < ActiveRecord::Base
belongs_to :company, :counter_cache => true
end
class CompaniesUsers < ActiveRecord::Base
belongs_to :company
belongs_to :user
end
The code works just fine, but I have been wondering if it's possible to:
I want to link a job with an employer, so think of this scenario: A user John who's an employee at Example, he posted the job Rails Developer, so I want to access #job.employer and it should get me back the user John, in other words:
#user = User.find_by_name('john')
#job = Job.find(1)
#job.employer == #user #=> true
So I thought of two possible solutions
First solution
class Job
has_one :employer, :through => :employers
end
class User
has_many :jobs, :through => :employers
end
class Employer
belongs_to :job
belongs_to :user
end
Second solution
class Job
has_one :employer, :class_name => "User"
end
class User
belongs_to :job
end
Which route should I go? Is my code right ?
I have another question, how to get rid of the class_name => "CompaniesUsers" option passed to has_many, should the class be Singular or Plural ? Should I rename it to something like Employees ?
P.S: I posted the same question to Ruby on Rails: Talk
Unless I'm missing something, I'd suggest simply doing
class Job
belongs_to :employer, :class_name => "User"
end
class User
has_many :jobs
end
This would give you methods like
user = User.first
user.jobs.create(params)
user.jobs # array
job = user.jobs.first
job.employer == user # true
You'll need an employer_id integer field in your Jobs table for this to work.
Typically you want to name your pass through model:
company_user
Then you don't need this:
class_name: "CompaniesUsers"
Just make sure the name of your database table is:
company_users
What you have works for you, so that's great. I just find when I don't follow convention I
run in to trouble down the road.
I have a the following polymorphic association set up:
class Favorite < ActiveRecord::Base
belongs_to :favoritable, :polymorphic => true
belongs_to :user
end
class Photo < ActiveRecord::Base
has_many :favorites, :as => :favoritable
belongs_to :user
end
What I ultimately want to do is pull all the photos a specific user has favorited.
How would I make that happen?
You could use the Active Record Query Interface for this:
Photo.joins(:favorites).where("favorites.user_id = ?", user_id)
This will return an Array of Photo objects (along with joined fields from Favorite) that a specific user has favorited. You'll have to pass in the user_id to this call.
Right down to business....
There are tasks, which have assigned users
class Task < ActiveRecord::Base
has_many :task_assignments, :dependent => :destroy
has_many :assigned_users, :through => :task_assignments, :source => :user
validates_associated :task_assignments
end
And users have assigned tasks
class User < ActiveRecord::Base
has_many :task_assignments, :dependent => :destroy
has_many :assigned_tasks, :through => :task_assignments, :source => :task
end
The task_assignments table looks like this
class TaskAssignment < ActiveRecord::Base
validates_presence_of :user, :message => 'You must add some USERS fool!'
belongs_to :user
belongs_to :task
end
Those associations seem to be working well :0)
Here's the rub - when I add a new task through /tasks/new, I also want to specify a list of users assigned to that task, which the form is returning in "params[:users_list][:id]".
I can get this to work, but I don't want the form to validate unless there is at least one user selected.
I can't for the life of me figure out how to get this validation to take place in the models rather than in the create method.
As you can see, I've thrown "validates _associated :task _assignments" in the tasks method, but to no avail. I'm clearly in over my head.
Thanks for your help.
I think you have to name the parameter user_ids...
f.e.:
params[:users_ids][:id]