Как добиться многого через отношения между пользователями - PullRequest
0 голосов
/ 06 сентября 2018

Я строю систему сопоставления между пользователями, изначально она имела и принадлежит многим ассоциациям, но из-за некоторых проверок и дополнительных данных, которые мне нужны для этой таблицы соединений, мне нужно иметь модель для нее и изменить ее на много через.

has_and_belongs_to_many(:likes,
    class_name: :User,
    join_table: :user_likes,
    foreign_key: :user_liker_id,
    association_foreign_key: :user_liked_id)

has_and_belongs_to_many(:likeds,
    class_name: :User,
    join_table: :user_likes,
    foreign_key: :user_liked_id,
    association_foreign_key: :user_liker_id)

Это старая реализация, которую нужно преобразовать в has_many через. Как видите, с помощью этого я могу получить всех пользователей, которые мне понравились, и пользователей, которые мне понравились. Я создал UserLike модель, но у меня не получилось добиться того, чтобы она работала внутри пользовательской модели Я уже попробовал следующее:

user.rb

has_many :user_likes
has_many :likes, through: :user_likes, foreign_key: :user_liked_id
has_many :likeds, through: :user_likes, foreign_key: :user_liker_id

user_like.rb

class UserLike < ApplicationRecord
    belongs_to :user
end

Эта реализация вызывает следующее исключение:

ActiveRecord :: HasManyThroughSourceAssociationNotFoundError: Не удалось найти ассоциацию (я) источника "like" или: likes в модели UserLike. Попробуйте 'has_many: likes,: through =>: user_likes,: source =>'. Это один из пользователей или user_likes?

Я не знаю, чего мне здесь не хватает, любая помощь будет оценена :)

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

При создании таблицы соединения, которая дважды объединяет одну и ту же таблицу, необходимо две отдельные ассоциации, поскольку пользователь может использовать любой внешний ключ:

class User < ApplicationRecord
  has_many :likes_as_liker,
    class_name: 'Like',
    foreign_key: 'liker_id'
  has_many :likes_as_liked,
    class_name: 'Like',
    foreign_key: 'liked_id'
end

class Like < ApplicationRecord
  belongs_to :liker, class_name: 'User'
  belongs_to :liked, class_name: 'User'
end

Создав две ассоциации has_many, мы можем начать создавать косвенные ассоциации:

class User < ApplicationRecord
  has_many :likes_as_liker,
    class_name: 'Like',
    foreign_key: 'liker_id'
  has_many :likes_as_liked,
    class_name: 'Like',
    foreign_key: 'liked_id'
  has_many :likers,
    through: :likes_as_liked
  has_many :liked_users,
      through: :likes_as_liker,
      source: :liked
end

Который отлично работает:

irb(main):002:0> u.likers
  User Load (2.8ms)  SELECT  "users".* FROM "users" INNER JOIN "likes" ON "users"."id" = "likes"."liker_id" WHERE "likes"."liked_id" = $1 LIMIT $2  [["liked_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>
irb(main):003:0> u.liked_users
  User Load (1.3ms)  SELECT  "users".* FROM "users" INNER JOIN "likes" ON "users"."id" = "likes"."liked_id" WHERE "likes"."liker_id" = $1 LIMIT $2  [["liker_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>
0 голосов
/ 06 сентября 2018

В соответствии с описанием, упомянутым в посте, вы пытаетесь найти пользователей, которым понравился мой пост, и пользователей, которые мне понравились.

В приведенном ниже коде не сказано, что лайки и лайки на самом деле являются пользователями.

has_many :user_likes
has_many :likes, through: :user_likes, foreign_key: :user_liked_id
has_many :likeds, through: :user_likes, foreign_key: :user_liker_id

Измените его ниже

has_many :user_likes
has_many :likes, through: :user_likes, foreign_key: :user_liked_id, source: :liked
has_many :likeds, through: :user_likes, foreign_key: :user_liker_id, source: :liked

Наилучший подход задает класс вместе с именем класса, чтобы рельсы знали, какой класс сопоставлен с этим внешним ключом при указании имен настраиваемых отношений

Когда имя вашей ассоциации отличается от имени, используемого в: through, вы должны определить параметр источника. Если вы посмотрите на сообщение об исключении, оно явно попросит вас сделать это.

Надеюсь, это ответит на вопрос.

...