Como faço para definir relações ActiveRecord entre dois modelos que relacionam entre si de duas maneiras diferentes?
Pergunta
No meu aplicativo eu tenho o usuário aulas, Vídeo e Votar. Usuários e vídeos podem se relacionam entre si de duas maneiras diferentes: como um um-para-muitos ou como muitos-para-muitos. O primeiro é quando um usuário envia um vídeo (um usuário pode enviar muitos vídeos). O último é quando um usuário vote sobre um vídeo (usuários têm muitos vídeos através de votos, e vice-versa). Aqui está o meu código, que não funciona (eu acho - eu possa estar fazendo algo errado no modo de exibição). Por favor, ajuda-me a compreender a maneira correta de estruturar essas associações:
class User < ActiveRecord::Base
has_many :videos, :as => :submissions
has_many :votes #have tried it without this
has_many :videos, :as => :likes, :through => :votes
end
class Vote < ActiveRecord::Base
belongs_to :video
belongs_to :user
end
class Video < ActiveRecord::Base
belongs_to :user
has_many :votes #have tried it without this . . . superfluous?
has_many :users, :as => :voters, :through => :votes
end
Solução
class User < ActiveRecord::Base
has_many :videos # Submitted videos
has_many :votes
has_many :voted_videos, :through => :votes # User may vote down a vid, so it's not right to call 'likes'
end
class Vote < ActiveRecord::Base
belongs_to :video
belongs_to :user
end
class Video < ActiveRecord::Base
belongs_to :user
has_many :votes
has_many :voters, :through => :votes
end
Mais detalhes podem ser encontrados aqui: http://guides.rubyonrails.org/association_basics.html
Hope isso ajuda =)
Outras dicas
Eu não tenho ido e verificados, mas é algo como isto:
Em vez de
has_many :videos, :as => :likes, :through => :votes
Use
has_many :likes, :class_name => "Video", :through => :votes
Mesmo com o baixo:
has_many :users, :as => :voters, :through => :votes
se torna
has_many :voters, :class_name => "User", :through => :votes
:as
é usado para associações polimórficas. Consulte neste capítulo em docs para mais informações.
Obrigado por sua ajuda caras, definitivamente me apontou na direção certa. Aqui está o código de trabalho:
class User < ActiveRecord::Base
has_many :videos, :as => :submissions
has_many :votes
has_many :likes, :source => :video, :through => :votes
end
class Vote < ActiveRecord::Base
belongs_to :video
belongs_to :user
end
class Video < ActiveRecord::Base
belongs_to :user
has_many :votes
has_many :voters, :source => :user, :through => :votes
end
PS Eu mantive-o como:. Gosta porque neste app não será capaz de downvote apenas upvote