0

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?

ShEsKo
  • 157
  • 1
  • 13

1 Answers1

1

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)

polymorphic

#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.

Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • Thank you for your answer, After reading this [post](http://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay) I decided that it would be best to store the photos as files and just use the photo entity in order to store the path in the database. From my understanding the avatar object of type photo actually saves the photo in the database. Is that right? Additionally, in the first solution it doesn't seem that users can share the same profile photo without needing to duplicate it. The belongs_to allow only one user foreign key, no? – ShEsKo Feb 03 '16 at 11:24
  • I presumed you were using something such as `Paperclip` to store the photos -- which stores them as *files*, referencing them in the db. Do you want me to detail how that pattern works? – Richard Peck Feb 03 '16 at 11:26
  • No, it's ok. I will have a read on it. Thank you for you help Rich! – ShEsKo Feb 03 '16 at 15:04
  • No problem. Be sure to let me know if you have any issues. [I met the Paperclip guys](https://pbs.twimg.com/media/Bx1T6G_CcAASYax.jpg) some time ago ^_^ – Richard Peck Feb 03 '16 at 15:10
  • Awesome! If I end up with any problem I'll let you know :) – ShEsKo Feb 03 '16 at 15:15