Rails polymorphic association that multiple models access the same thing - ruby-on-rails

How do you set up a polymorphic association where two different models have access to the same item
class Image < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
class ModelA < ActiveRecord::Base
has_many :images, :as => :imageable
end
class ModelB < ActiveRecord::Base
has_many :images, :as => :imageable
end
I would like ModelA and ModelB to access the same Image. So if ModelA updates an image ModelB image will be updated also.
UPDATE
I am attempting to create something like the following
Event has many images
Person has many images
Person and Event reference the same image
When a image is added to a person from an Event the record has extra attributes.
Can this be done though a polymorphic association?
Thank you

I think you should use the relation between ModelA and ModelB to do this. Because images are not shared within ModelA. eg:
ModelA.find(1).images
is different from
ModelA.find(2).images
EDIT
If i understand correctly, you dont need a polymorphic relation here.
You can just create this relation
In Person Model
has_many :event_images, :through => :person_event_images

Related

change type in polymorphic association in rails

I am new to rails and I'm using rails Polymorphic association and I ran into a problem
I have two models EmployeeTable and ProductTable. Both have some picture in Picture Model
class Picture < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
class EmployeeTable < ActiveRecord::Base
has_many :pictures, as: :imageable
end
class ProductTable < ActiveRecord::Base
has_many :pictures, as: :imageable
end
there are two column in Picture imagable_id and imagable_type. When I create an entry in table it stores imagable_type as either "EmployeeTable" or "ProductTable". Can I change these name to any different Names like "employee" and "product".
Thanks in advance
To retreive the image_type without with table, you can add this method in your model. Changing the assosiated model name while saving will cause issues while querying
def neat_imageable_type
self.imageable_type.gsub("Table", "").downcase
end

Composite foreign keys in Rails ActiveRecord

I currently have a model named Image. This model is tied to an Article.
class Article < ActiveRecord::Base
has_many: images
end
The Image table contains an article_id, so an image is associated with an article.
However, I would like to use my images together with other models as well. Therefore I imagine changing article_id into something like owner_id and add a new attribute called owner_model to the Image model.
That way other models can also have many images.
Any idea if this is possible to achieve gracefully using ActiveRecord and how to go about it?
On a sidenote, I am using CarrierWave for images.
You can use polymorphic associations.
The rails guide has a neat example that goes with your question.
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
end
Have you looked into polymorphic associations? Ryan has a video up on it: http://railscasts.com/episodes/154-polymorphic-association
It will allow you to associate different classes with your images.
What you are looking for is called polymorphic associations ( http://guides.rubyonrails.org/association_basics.html#polymorphic-associations ).

Polymorphic associations and/or has_many_through

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.

Using Rails, not sure if I should use belongs_to or not

Very new to Rails... I'm building out functionality that lets people compare photos, and I can't decide exactly how I should structure it. Ideally what I'd like is to have a "comparisons" table which keeps a record of the IDs of the photos compared as well as the user that compared them, but I'm not quite sure whether this warrants use of the "belongs_to" function or not. If so, how do I specify that each comparison belongs to TWO separate photos?
The following has_many, :through => Model structure will let you have additonal properties on the join table, e.g. 'comparing_user_id'.
class Photo < ActiveRecord::Base
has_many :appearances
has_many :users, :through => :appearances
end
class Appearance < ActiveRecord::Base
belongs_to :photo
belongs_to :user
end
class User < ActiveRecord::Base
has_many :appearances
has_many :photos, :through => :appearances
end

Rails data modeling - alternatves to has_many :through, given polymorphism?

I'm working on an application that allows users to associate images with specific events. Events are owned by a user. The easy solution would of course be:
class Image < ActiveRecord::Base
belongs_to :event
end
class Event < ActiveRecord::Base
has_many :images
belongs_to :user
end
class User < ActiveRecord::Base
has_many :events
has_many :images, :through => :events
end
Except! There is one problem. I also want my users to be able to own images directly, without an intermediary event. If I use polymorphic association "conventionally" here, then obviously user.images won't work properly. Should I just hold my nose, use an :as => :event_images to disambiguate, and define user.all_images if that need ever comes up? Should I have all images owned directly by users and optionally associated with events somehow? (With, of course, a validation to ensure consistency... but that seems code-smelly.) Is there a third solution that is prettier than either of these?
I often find it useful to forget the ActiveRecord DSL and work with the data model directly when defining complex relationships. Once the data model is correct you can then map it into model statements.
It is not quite clear from your question if Images can be owned by a User or an Event, of if they can be owned by both at the same time. That issue will determine the data model you use.
If an Image can be owned by both, the Image table will need a reference to both a user_id and an event_id, which may need to be nullable depending on your use-case (user or event being optional relationships). If the Image can only be owned by one, you could set up some sort of polymorphic ownerable relationship that maps owners to the right owner table (owner_id, owner_type etc etc).
Assuming it can belong to both:
class Image < ActiveRecord::Base
belongs_to :event
belongs_to :user
end
class Event < ActiveRecord::Base
has_many :images
belongs_to :user
end
class User < ActiveRecord::Base
has_many :events
has_many :images
has_many :event_images, :through => :events, :class_name => "Image"
end

Resources