Rails Model user adding player to user pinboard

亡梦爱人 提交于 2019-12-13 04:31:36

问题


I'm creating a sports application which allows users to create pinboards, as many as they like. The users can then add say their favorite player to a specified pinboard. So for example User: Jack, creates a new pinboard called "My favorite defenders", He can then go and find his favorite defenders, say Kevin Garnet, and add/pin garnet to his "My favorite defenders" Pinboard.

I have a Users model, a Pinboards Model and a Players model. I tried the following association but didn't work as I wanted.

User

has_many :pinboards
has_many :pins, through: pinboards, source: :player

Pinboard

belongs_to :user
belongs_to :player

I know a player can't have many pinboards and a pinboard will hold many players. How can I get the behavior i want; User creates pinboard---user adds player to pinboard.


回答1:


User

has_many :pin_boards
has_many :pins, through: :pin_boards, source: :players


PinBoard

belongs_to :user
has_many :pin_board_player_assignments
has_many :players, through: :pin_board_player_assignments


PinBoardPlayerAssignment

belongs_to :pin_board
belongs_to :player


Player

has_many :pin_board_player_assignments
has_many :pin_boards, through: :pin_board_player_assignments

So, basically, you'll need to add another model called PinBoardPlayerAssignment. From there, I'd highly recommend using this join model to create and manage the assignments, like so:

PinBoardPlayerAssignment

def self.create_between(a_pin_board, a_player)
  assignment = a_pin_board.pin_board_player_assignments.build
  assignment.player = a_player
  assignment.save!
end

This way, you can use instance methods on PinBoard or on Player to DRYly create the assignment between the PinBoard and the Player. Basically, let the object that knows the most about pin_boards and players be the one to manage the relationships between them.

PinBoard

def add_player(a_player)
  PinBoardPlayerAssignment.create_between(self, a_player)
end


Player

def add_to_pin_board(a_pin_board)
  PinBoardPlayerAssignment.create_between(a_pin_board, self)
end

And the great thing is that Rails 3.2+ allows nested :through relationships so your original request -- to have @user.pins should compile the result of going through the pin_board and then through the pin_board_player_assignment table automatically.




回答2:


Try:

has_many :pins, through: :pin_boards, source: :players

The key is to make the source be the exact same as the relationship in the join model. So, since your join model (PinBoard) almost certainly says has_many :players then you have to match that word players exactly. So you were just missing the 's'.



来源:https://stackoverflow.com/questions/18552896/rails-model-user-adding-player-to-user-pinboard

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