I have four models, let's call them Cars and Houses. Users can have multiple cars, and multiple houses. Cars and Houses belong to Users. I'd like users to be able to upload multiple photos of their cars, and multiple photos of their houses, and from what I've read this means creating a new model called 'Photos'. Is it possible for two different models to both have_many Photos, and for Photos to belong_to more than one model? I'm using Ruby 2.0.0 and Rails 4.
Sketch / PseudoRuby
User
has_many :cars
has_many :houses
Car
belongs_to :user
has_many :photos
House
belongs_to :user
has_many :photos
Photo
belongs_to :car, :house
Is this relationship ok? I wasn't sure if I had to make separate models for the photos of Car and House.
From a Rails standpoint, yes you can do it. The belongs_to association tells Rails to keep the foreign_key in the Photo model. So in your example, your photos table will have 2 foreign keys :
car_id which will point to the associated car id (primary key) from the cars table.
house_id which will point to the associated house id (primary key) from the house table.
Now, from the paperclip standpoint, you can have as many photos for a particular model as you want. But, in order to have the same Photo model associated to both House and Car, you need to use polymorphic association.
Your model will be similar to this :
class Photo < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
has_attached_file :photo, styles: {}
end
class Car < ActiveRecord::Base
has_many :photos, as: :imageable
end
class House < ActiveRecord::Base
has_many :photos, as: :imageable
end
You can get more information about polymorphic associations here: http://guides.rubyonrails.org/association_basics.html
Related
In the models of my app I want to have the option that the owner of each record is a user or a company...
Normally I have a user_id field (user model) in each model for keeping the owner...
What are the implementation options for this?
How can I design this?
Should I add another field in the models? owner? how can I use the user_id (user_model) or the company_id (company model)?
The data in the app could be:
Personal data of the specific user
Company data, which are separated from Personal data. Ofcourse company data also created by a certain user which is a member (with certain role) of the company...
Any ideas?
Thank you
this can be done with polymorphic associations, you have a model that can belongs to more than 1 model with the same relationship, see this example
class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end
class Employee < ApplicationRecord
has_many :pictures, as: :imageable
end
class Product < ApplicationRecord
has_many :pictures, as: :imageable
end
for this to work you need to create an imageable_id and imageable_type on your picture table, fir this example.
you can check more information about this on rails documentation
My app has 5 core models. I'm trying to figure out the best way to associate the models. How many tables should I build and which kind etc?
Here are the associations I would like to include and their respective models:
User
Has many boards
Has many lists
Has many cards
Has many comments
Board
Has many users
Has many lists
Has many cards
List
Belongs to board
Has many cards
Card
Belongs to board
Belongs to list
Has many comments
Comment
Belongs to card
Belongs to user
class User < ActiveRecord::Base
has_and_belongs_to_many :boards
has_many :lists, as: listable
has_many :cards, as: cardable
has_may :comments, as: commentable
end
class Board < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :lists, as: listable
has_many :cards, as: cardable
end
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
end
class List < ActiveRecord::Base
belongs_to :listable, :polymorphic => true
has_many :cards, as: cardable
end
class Card < ActiveRecord::Base
belongs_to :cardable, :polymorphic => true
has_many :comments, as:commentable
end
To establish HABTM relation you have to create a table named 'users_boards'
As Board and User are having many to many relationship, there will be a new table for it, if you want HABTM you can use it.
User(id, name, other_attributes...)
Board(id, name,...)
List(id, name, user_id(fk),...)
Card(id, name, user_id(fk), list_id(fk), board_id(fk),...)
Comment(id, comment_msg, user_id(fk), card_id(fk),...)
Board_User(board_id(fk), user_if(fk)) --- M-M relation
Few attributes might change if there is a has_many through relation.
FK-- Foreign key, you can use has_many through depending on your requirements.
Using polymorphic associations has some limitations, so please do through it then decide to use a polymorphic association
http://codeblow.com/questions/pros-and-cons-for-ruby-on-rails-polymorphic-associations/
I created a new rails application called imdb. I have created two models (via scaffolding) called User and Movie. I ran this in terminal.
rails g scaffold Movie title:string review:text location:string
rails g scaffold User name:string password_digest:string
I am finding it hard to imagine the associations that can be implemented into my application and need some help figuring this through.
We have these associations:
belongs_to,
has_one,
has_many,
has_many :through,
has_one :through,
has_and_belongs_to_many
I have so far thought that a 'user' can have many 'movies' and a 'movie' can have many 'users', but unfortunately my mind has gone blank! Help would be greatly appreciated.
Thanks.
This probably seems confusing to you because there may not be any direct relationship between movies and user. If you had a third model Review this may make more sense.
class Movie < ActiveRecord::Base
has_many :reviews, inverse_of: movie
end
class User < ActiveRecord::Base
has_many :reviews, inverse_of: user
end
class Review < ActiveRecord::Base
belongs_to :movie
belongs_to :user
end
I would create something like
Class User
has_many :movies
Class Movie
Belong_to :users
has_many :reviews :as => :reviewable
class Review
Belongs_to :movie
or
belongs_to :user
belongs_to :reviewable :polymorphic => true (this way this class can be reused later for more than movies and always written by user)
has_many :comments :as => :commentable etc.
It is similar to a case where A user may have many roles, and a role may have many users when you work with permissions (admin, user, guest, banned, etc...).
If I wanted to create a model that could be used in association with other models independently I would use a Polymorphic association as Richardlonesteen. ex: I want to have reviews written by users for books and movies, but a review belongs either to a book or movie and not both.
Your solution is to use the has_many :through association. You will have 3 models: User, Movie, and another model that will tie the relationship between the Users and the Movies. For example purpose we will call this third model Screening, but it can be anything else. When you create you Screening model, you will also need a migration with two columns user_id:integer movie_id:integer, and make sure you index them both.
Your user.rb
class User < ActiveRecord::Base
has_many :movies, :through => :screenings
has_many :screenings
attr_accessible :username
end
Your movie.rb
class Movie < ActiveRecord::Base
has_many :users, through => :screenings
has_many :screenings
attr_accessible :name
end
Your screening.rb
class Screening < ActiveRecord::Base
# attributes are :user_id and :movie_id
belongs_to :user
belongs_to :movie
end
Resulting with a relationship table that would look something like this
user_id | movie_id
------------------
1 | 1
------------------
1 | 2
------------------
2 | 1
------------------
3 | 2
Once you have this setup, you can fetch all movies of a user by doing #user.movies and vice-versa #movie.users. Rails will know how to find the associations.
I need to create relationships between a user, product and a photo-model. A user can add photos to a product. Therefore, a user has_many photos and a product has_many photos, but each photo belongs_to both a product and a user. How can I achieve this in Rails? As far as I understand a polymorphic association would only allow a photo to belong to a product or a user. Do I have to instead using separate has_many_through relationships for the user-photo and product-photo relationships?
You can have multiple belongs_to attributes within the same model. Essentially the Model that is marked as belongs_to will hold a foreign key to the Model that has been marked with has_many.
class MyModel < ActiveRecord::Base
belongs_to :other_model1
belongs_to :other_model2
end
If you want to use polymorphic associates as you mentioned below you could do that along these lines
class Photos < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
end
class Users < ActiveRecord::Base
has_many :photos, :as => :imageable
end
class Product < ActiveRecord::Base
has_many :photos, :as => :imageable
end
In this case you can create the relationship simply by adding the has_many :phots, :as => :imageable attribute without having to revisit the Photos class.
I have an app where:
User has_many Openings
Opening belongs to User & has_and_belongs_to_many Categories
Category has_and_belongs_to_many Openings
I'm trying to create a rating system where the user rates each opening per category, and am struggling to see what relations I need where. Could anyone help point me in the right direction please?
Basically I want the rating to belong to a opening_category relation.
Instead of using has_and_belongs_to_many association, you want the has_many through relation
Thus, you create a new model
class OpeningCategory
belongs_to :opening
belongs_to :category
end
Then you can use Opening has_many :categories, :through => :opening_categories, and Category has_many :openings, :through => :opening_categories.
Your rating can be done with the OpeningCategory, whether that is an average rating column, or a separate Rating model which :belongs_to :opening_categories.