Many-to-many connection and Associations

不羁岁月 提交于 2019-12-04 21:34:52

Your problem #1 is a textbook case of polymorphic association.

class User < ActiveRecord::Base
  has_one         :show,
                  :dependent => :destroy
  has_many        :clips,
                  :dependent => :destroy
  has_many        :albums,
                  :dependent => :destroy
end

class Clip < ActiveRecord::Base
  belongs_to      :user
  belongs_to      :attachable,
                  :polymorphic => true
end

class Show < ActiveRecord::Base
  belongs_to      :user
  has_many        :clips,
                  :as => :attachable
end

class Album < ActiveRecord::Base
  belongs_to      :user
  has_many        :clips,
                  :as => :attachable
end

You can learn more about polymorphic associations at Rails Guides.

Now for your problem #2, assuming you do your migrations as per the guide linked above you'll have two database fields in your clips table:

  • attachable_id - This is the id of the instance of Show or Album that's going to receive the association.
  • attachable_type - This is the class name of the target object, so either Show or Album.

In your upload form, you're going to show a list of shows and/or albums and assign the id to attachable_id and the class name to attachable_type.

I would suggest loading up your initial select with only one class and then replacing its contents via JavaScript in case the user selects the second option. Like so:

<%= f.collection_select :attachable_type, [['Show'], ['Album']], :first, :first, { :selected => 'Show' }, { :include_blank => false } %>
<%= f.collection_select :attachable_id, Show.all, :id, :name %>

I think that unless there's some reason they all must belong to the user, you can simplify this a lot by making better use of your clip model.

Change your relationships to this:

User.rb

has_many :clips, dependent: :destroy

Clip.rb

belongs_to :user
has_one :show
has_many :albums

Show.rb

belongs_to :clip

Album.rb

belongs_to :clip

You can see the show by using clip.show and the albums by using clip.albums - individual albums can be called by using clip.albums.find(params[:id])

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!