开发者

has_many :through object inhertiance

开发者 https://www.devze.com 2023-02-16 04:09 出处:网络
I am trying to make an application wherein Users have many Items, and each Item they have through Possession is an entity in its own right. The idea behind this is if I have a MacBook item, eg, and a

I am trying to make an application wherein Users have many Items, and each Item they have through Possession is an entity in its own right. The idea behind this is if I have a MacBook item, eg, and a user adds it to their inventory, they may apply attributes (photos, comments, tags, etc) to it without directly affecting them Item itself, only their Possession.

The Item will in turn aggregate attributes from its corresponding Possessions (if you were to go to /item/MacBook, rather than /user/101/possession/5). I have the following models setup (ignoring attributes like photos for now).

class U开发者_如何学Cser
    has_many :possessions
    has_many :items, :through => :possessions
end

class Item
    has_many :possessions
    has_many :users, :through => possessions
end

class Possession
    belongs_to :user
    belongs_to :item
end

My first question is, am I doing this right at all. Is has_many :through the right tool here?

If so, how would I deal with class inheritance here? I might not be stating this right, but what I mean is, if I were to do something like

@possession = Possession.find(params[:id])
@photos = @possession.photos.all

and there were no photos available, how could it fall back to the corresponding Item and search for photos belonging to it?


Your initial data structure seems appropriate.

As for the second part, with the "fall back" to a corresponding item, I don't think there would be a direct Active Record way of doing this. This behavior seems pretty specific, and may be confusing to future developers working on your app unless you have a clear method for this.

You could create a method inside Possession like:

def photos_with_fallback
   return self.photos if self.photos.size > 0
   self.item.photos
end

There is a huge consequence to doing this. If you have a method like this, you won't be able to do any write activities down the wrode like @photos.build or @photos.create because you won't know where you're putting them. They could be linked to the Item or the Posession.

I think you're better of pushing the conditional logic out to your controller and checking for photos on the Posession first and then on the Item.

#In the controller
@photos = @posession.photos
@photos = @posession.item.photos if @photos.size == 0

This will be more clear when you go to maintain your code later, and it will allow you to make other decisions down the road.

0

精彩评论

暂无评论...
验证码 换一张
取 消