I have a small app which has Users, Recipes, Ingredients and preparation models
A user has many recipes, recipes belong to user and ingredients/preparation belongs to recipes.
Now a user can view all recipes but I would like the option to add the particular recipe to a favourites list. Would I need to set a new DB to hold this and then link by associations or could I add a column to the recipe model called fav for example?
Im looking for the best practice here or if someone has done this before and can offer any advice that would be appreciated
I think you can set has_may association like this:
class User < ActiveRecord::Base
has_many :favorite_recipes, foreign_key: "user_id", class_name: "Recipe", dependent: :destroy
end
I would add a boolean column favorited to your UsersRecipe table.
Then you can add a scope for this in your User model:
has_many :favorite_recipes, :through => :user_recipes, :class => Recipe, :conditions => ['user_recipes.favorited = ?',true]
Related
I'm trying to figure out the best way to model a many-to-one relationship in rails where there are multiple scopes to the relationship.
An example would be a restaurant has-many photos. I want to be able to call
restaurant.lounge_photos
and receive only the lounge photos,
but also be able to call
restaurant.food_photos
and receive just the food photos.
The two methods I can think of are:
to use multiple joins table, and a has_many to has_one relationship for each type of photo.
to add a 'type' attribute to the photo model and write a scoping method.
Both of these seem a bit clunky to me.
Is there a better solution here?
I think you have to go has_many and Single Table Inheritance(STI), as follow.
Make association with restaurant and photo
class Restaurant < ActiveRecord::Base
has_many :photos
end
class Photo < ActiveRecord::Base
belongs_to :restaurant
end
Then you have to use STI in Photo model. The reason is that you have almost all fields are common for lounge_photos and food_photos.
OR
Using scope directly you can differentiate it and achieve your goal.
For more details of use STI you can refer this link.
This is one way, using a type column
has_many :food_photos,
class_name: 'Photo',
foreign_key: :restaurant_id,
-> { where(type: 'food') }
has_many :lounge_photos,
class_name: 'Photo',
foreign_key: :restaurant_id,
-> { where(type: 'lounge') }
I have users and companies in a many to many relationship by a join table which has a column for user Role. I'm not sure if this is the best way to have the model set up.
Now each user can have different roles depending on the company, what is the best way to design and access user's role using ActiveRecord associations?
I would like to return via JSON the user's role based on their current company and default to something if their company is nil OR their role has not been set (nil).
Update:
What I've got now after reading Many-to-many relationship with the same model in rails? which is a bit different (many to many on itself).
CompaniesUser
belongs_to :company
belongs_to :user
Company
has_many(:companies_users, :dependent => :destroy)
has_many :users, :through => :companies_users
User
has_one :company
has_many(:companies_users, :dependent => :destroy)
has_many :companies, :through => :companies_users
Appreciate any advice as I'm just starting to learn this!
What you have above is correct, in terms of the ActiveRecord relationships. If you'd like to read more on the subject I believe this is the best source: http://guides.rubyonrails.org/association_basics.html
One problem I see there is that CompaniesUsers should be in singular form: CompanyUser, and then in all cases where you use :companies_users use: :company_users
I am assuming here that the current company of the User is the last one assigned.
Now in order to serialize in JSON format you should add the following in your User ActiveRecord:
def serializable_hash(options = nil)
options ||= {}
h = super(options)
if(defined?self.company_users.last and defined?(self.company_users.last).role)
h[:role] = (self.company_users.last).role
else
h[:role] = 'default_value'
end
end
I have a many to many :through relationship between a set of classes like so:
class Company
has_many :shares
has_many :users, :through => :shares, :uniq => true
end
class User
has_many :shares
has_many :companys, :through => :shares, uniq => true
end
class Share
belongs_to :company
belongs_to :user
end
I want to ensure a unique relationship so that a user can only have one share in any one company, which is what I have tried to achieve using the "uniq" argument.
At first I thought this was working, however it seems the behaviour os the "uniq" is to filter on the SELECT of the record, not pre-INSERT so I still get duplicate records in the database, which becomes an issue if I want to start dealing with the :shares association directly, as calling user.shares will return duplicate records if they exist.
Can anyone help with an approach which would force truely uniq relationships? so that if I try adding the second relationships between a user and a company it will reject it and only keep the original?
Have you tried adding this to your Share class?
validates_uniqueness_of :user, scope: :company
Also, in your User class I think it should be:
has_many :companies, through: :shares
I hope that helps.
I have a problem with fetching data from DB, where is between models association kind through.
On my site, I have a categories, like a sports, news, weather etc. When an user is logged in and has a selected the categories, from which want to see the articles, then I would like to display only these articles.
Here's how looks like my models:
class User < ActiveRecord::Base
has_many :user_categories
has_many :categories, :through => :user_categories
end
class Category < ActiveRecord::Base
has_many :articles
has_many :user_categories
has_many :users, :through => :user_categories
end
class UserCategory < ActiveRecord::Base
belongs_to :user
belongs_to :category
end
class Article < ActiveRecord::Base
belongs_to :category
end
But I still can't find the way, how to get all articles from user's selected categories... I tried something like
Article.joins("LEFT JOIN categories ON category.id = user_categories.category_id").where('user_categories.user_id = ?', current_user.id)
I would grateful for every advice!
Thank you
Here's one way to do it:
Article.where(:category_id => current_user.categories.map {|c| c.id})
That will create 2 queries. First one will return a list of the current user's categories. Then the ruby map function will create an array containing the ids of those categories. The second query will then return a list of articles whose category_id is in the array of ids. The second query will look something like:
select articles.* from articles where articles.category_id in(1,2,3);
I'm pretty new to Rails, and i'm trying to do a polymorphic HABTM relationship. The problem is that I have three models that I want to relate.
The first one is the Event model and then are two kind of attendees: Users and Contacts.
What I want to do is to be able to relate as an attendee both users and contacts. So, what i have right now in my code is:
Event Model
has_and_belongs_to_many :attendees, :polymorphic => true
User Model
has_and_belongs_to_many :events, :as => :attendees
Contact Model
has_and_belongs_to_may :events, :as => :attendees
How the HABTM table migration needs to be? I'm a little confused and i have found no help on that.
Is it going to work?
No, you can't do that, there's no such thing as a polymorphic has_and_belongs_to_many association.
What you can do is create a middle model. It would probably be something like this:
class Subscription < ActiveRecord::Base
belongs_to :attendee, :polymorphic => true
belongs_to :event
end
class Event < ActiveRecord::Base
has_many :subscriptions
end
class User < ActiveRecord::Base
has_many :subscriptions, :as => :attendee
has_many :events, :through => :subscriptions
end
class Contact < ActiveRecord::Base
has_many :subscriptions, :as => :attendee
has_many :events, :through => :subscriptions
end
This way the Subscription model behaves like the link table in a N:N relationship but allows you to have the polymorphic behavior to the Event.
Resolveu parcialmente.
It does solve the problem given the framework that we have at our disposal, but it adds "unnecessary" complexity and code. By creating an intermediary model (which I will call B), and given A -> B -> C being "A has_many B's which has_many C's", we have another AR Model which will load one more AR class implementation into memory once it is loaded, and will instantiate for the sole purpose of reaching C instances. You can always say, if you use the :through association, you don't load the B association, but then you'll be left with an even more obsolete model, which will only be there to see the caravan pass by.
In fact, this might be a feature that is missing from Active Record. I would propose it as a feature to add, since it has been cause of concern for myself (that's how I landed in this post hoping to find a solution :) ).
Cumprimentos