Reputation: 157
I have two questions about ActiveRecords:
1)
Let's say I have an application with several users, each one of which has a profile photo.
I would like users to be able to have the same profile photo as their friends: this leads to a 1-many relationship where one photo can be the profile photo of many users.
When I have to create the association in rails I have to write something like this:
class User < ActiveRecord::Base
belongs_to :photo
end
class Photo < ActiveRecord::Base
has_many :Users
end
Now this seems a bit weird to me since the photo belongs to multiple users in this case, rather than multiple users belonging to one photo.
I am doing this wrong or am I overthinking about the terminology of rails?
2)
New Case:
Let's say a user can have one profile photo. In this case the photo cannot be shared between users, as a consequence the relationship is of 1-to-1.
I also want to add a post entity which can contain a photo and this photo can be used by a user as a profile photo.
This is how the final implementation would look like:
class User < ActiveRecord::Base
has_one :photo
end
class Photo < ActiveRecord::Base
belongs_to :user
belongs_to :post
end
class Post < ActiveRecord::Base
has_one: Photo
end
By looking at the Rails Documentation it seems that the only way to create the one to one relationship as such is by putting the two foreign keys in the Photo table: one for Post and one for User.
However I would like to instead have one foreign key in the User table for Photo and one foreign key in the post table for Photo as well. In this case it seems that the implementation needs to be as such:
class User < ActiveRecord::Base
belongs_to :photo
end
class Photo < ActiveRecord::Base
has_one :user
has_one :post
end
class Post < ActiveRecord::Base
belongs_to: Photo
end
This also does not make much sense to me, semantically speaking. Again, am I going something wrong or am I overthinking this?
Upvotes: 0
Views: 119
Reputation: 76784
1)
#app/models/user.rb
class User < ActiveRecord::Base
has_one :photo
belongs_to :avatar, class_name: "Photo" #-> set this as the "avatar"
end
#app/models/photo.rb
class Photo < ActiveRecord::Base
belongs_to :user
end
The user
can create a photo; he can define which avatar
he uses:
@user = User.find x
@photo = @user.avatar
Whilst I still think it looks a little weird, I think it would work.
2)
#app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
has_one :photo, as: :imageable
end
#app/models/user.rb
class User < ActiveRecord::Base
has_many :posts
has_one :photo, as: :imageable
belongs_to :avatar, class_name: "Photo"
end
#app/models/photo.rb
class Photo < ActiveRecord::Base
belongs_to :imageable, polymorphic: true #-> belongs to either post or user
end
In both cases, I would advocate using a foreign_key
to define the avatar_id
for the user.
This will mean a belongs_to
association (not ideal), but will mean that you can upload as many images as you want, referencing one to be the avatar. You'll then be able to call the avatar
method as required in your profile.
The best way to do this would be to use a join table
/ join model
but that would be inefficient for what you're asking.
Upvotes: 1