Ok so I’m having a slight problem building my CMS for a client. I want to utilize the same model to handle the photos for their case studies as well as their services. Each has their own model. So the Photo model belongs to a Project or a Service. But in reality it belongs to a project OR a service. Thus I have a problem using acts_as_list.
class Photo < ActiveRecord::Base
belongs_to :service
belongs_to :project
acts_as_taggable
acts_as_list :scope => :project_id
file_column :image, :magick => { :versions => { "thumb" => "50x50", "medium" => "640x480>" } }
end
If I could do something like:
acts_as_list :scope => :project_id || :service_id
Then this would be a piece of cake but it’s not that easy. How would you solve this? I know it’s not that challenging.
Josh Knowles Says:
2:57 amAug 24It’s late, heading to bed, figured I’d try and point you in right direction, not sure if this will make sense or work
What if we change your domain model a tad… Instead of a Photo belonging to both Project or Service what if it belonged to an Album. You could then have a Project/Service belong_to an album (we use belong_to here so that the foreign key gets placed on the project table as opposed to having to have a project_id and service_id on each album). You then add an has_many :through to get direct access to the Photos.
Example (note writing from memory check for typos/syntax errors):
Josh Knowles Says:
2:58 amAug 24It’s late, heading to bed, figured I’d try and point you in right direction, not sure if this will make sense or work
What if we change your domain model a tad… Instead of a Photo belonging to both Project or Service what if it belonged to an Album. You could then have a Project/Service belong_to an album (we use belong_to here so that the foreign key gets placed on the project table as opposed to having to have a project_id and service_id on each album). You then add an has_many :through to get direct access to the Photos.
Example (note writing from memory check for typos/syntax errors):
Josh Knowles Says:
3:00 amAug 24(note have attempted to add comment couple times but it isn’t displaying all the code… too tired to figure out so I butchered it a bit trying to make it submit correctly, you should still get the general idea)
It’s late, heading to bed, figured I’d try and point you in right direction, not sure if this will make sense or work
What if we change your domain model a tad… Instead of a Photo belonging to both Project or Service what if it belonged to an Album. You could then have a Project/Service belong_to an album (we use belong_to here so that the foreign key gets placed on the project table as opposed to having to have a project_id and service_id on each album). You then add an has_many :through to get direct access to the Photos.
Example (note writing from memory check for typos/syntax errors):
Bogdan Says:
4:31 amAug 24With polymorphic associations..
class Project :addressable end class Service :addressable end class Image true acts_as_list :scope => '(addressable_id = #{addressable_id} AND addressable_type = "Project") OR (addressable_id = #{addressable_id} AND addressable_type = "Service")' endIt is based on polymorphic relationships and this excerpt from the documentation: it’s also possible to give it an entire string that is interpolated if you need a tighter scope than just a foreign key. Example: acts_as_list :scope => @todo_list_id = #{todo_list_id} AND completed = “”.
Hope it’s useful. Haven’t tested it though.
Jim Says:
8:37 amAug 24Hey Josh,
Sorry for the confusion if the comments weren’t showing up! My comments are all moderated.. my site gets a lot of spam comments like over a dozen a day. Once you’ve been approved you are free to comment from that point onward.
Jim Says:
8:40 amAug 24Thanks Bogdan! Your response is definitely interesting but I believe Josh’s method is the more ‘rails’ way to solve the situation.
Josh Knowles Says:
1:05 pmAug 24While I like have the more explicit Domain Model myself, Bogdan’s solution is correct and may actually be simplier if you don’t need the concept of an Album object. See http://wiki.rubyonrails.org/rails/pages/SimplePolymorphicAssociation for some explanation of what a Polymorphic Association is.
You don’t even need the fancy scope that he is using, you can just get away with doing :scope => ‘addressable_id’
Josh
Bogdan Says:
4:00 pmAug 24Nice solution Josh. Definitely more simplistic, more like CRUD.
(Sorry Josh, for the incomplete code, but it seems that the comment is somehow “escaped”)
seasonfive Says:
11:32 amMay 04I had exactly the same problem.
I used polymorphism which is a more generic way to manage than the Album solution (allow each entity to have one or severals picture without database modification) and that works well :
class Picture true file_column :file, :magick => { :versions => { ... } } acts_as_list :scope => 'gallery_type = \'#{gallery_type}\' AND gallery_id = \'#{gallery_id}\'' end Then in the Content model : class Content :gallery ... end and in the Car model : class Car :gallery ... endHope this could help.
seasonfive Says:
11:34 amMay 04Sorry for the double post but seems my Picture model wasn’t pasted correctly :-p
class Picture true file_column :file, :magick => { :versions => { ... } } acts_as_list :scope => 'gallery_type = \'#{gallery_type}\' AND gallery_id = \'#{gallery_id}\' AND session = \'#{session}\'' end(Hope this will work this time …)
seasonfive Says:
11:35 amMay 04Arghhh none of the class pasted well … Sorry to poluate your blog man. I would be able to edit my post but i can’t. Here the Content and Car model which could have Picture :
seasonfive Says:
11:36 amMay 04Last try …