Как будет работать «комментируемая» полиморфная ассоциация на самой «пользовательской» модели? - PullRequest
0 голосов
/ 21 апреля 2019

Я изучаю рельсы и пробую полиморфную ассоциацию. Я перечислил пару простых моделей для иллюстрации. Модельные ассоциации, кажется, работают нормально, как и ожидалось. Но что, если пользователь (комментатор) хотел бы оставить комментарий для другого пользователя? Я не могу заставить его работать с этими настройками. Как мне это сделать?

class User < ApplicationRecord
  #  username, email, password_digest
  has_many :comments, as: :commentable, dependent: :destroy
end

class Project < ApplicationRecord
  # title, completed, user_id
  has_many :comments, as: :commentable, dependent: :destroy
end

class Comment < ApplicationRecord
  # commenter_id, commentable_type, commentable_id, body
  belongs_to :commentable, polymorphic: true
end

в консоли ... setup

user1 = User.frist
user2 = User.last
project = Project.first

pro_comment = project.comments.new(body: 'some text')
pro_comment.commenter_id = user1.id
pro_comment.save

user_comment = user2.comments.new(body: 'some text')
user_comment.commenter_id = user1.id
user_comment.save

ожидаемые и фактические результаты

Comment.all => successfully lists pro_comment & user_comment

But...
Comment.find_by(commenter_id: 1) => only listed the pro_comment 
(what am I doing wrong?)

Также .. user1.comments => возвратил пустой объект ... ожидал 2 объекта, как вы можете видеть ниже, он не ссылается на 'commenter_id' .... результат ...

comment Load (0.5ms)  SELECT  "comments".* FROM "comments" WHERE 
"comments"."commentable_id" = $1 AND "comments"."commentable_type" = $2 
LIMIT $3  [["commentable_id", 1], ["commentable_type", "User"], 
["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>

Я тоже пытался ... user1.comments.where (commenter_id: 1) >> который возвратил ...

comment Load (0.4ms)  SELECT  "comments".* FROM "comments" WHERE
 "comments"."commentable_id" = $1 AND "comments"."commentable_type" = $2 
AND "comments"."commenter_id" = $3 LIMIT $4  [["commentable_id", 1],
["commentable_type", "User"], ["commenter_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::AssociationRelation []>

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

1 Ответ

2 голосов
/ 21 апреля 2019

find_by возвращает только одну запись, вместо этого попробуйте Comment.where(commenter_id: 1).

Если пустое значение user1.comments, вы смешиваете отношения.У вас должно быть 2 отношения: комментарий принадлежит комментируемому объекту (проекту или пользователю) и комментарии также принадлежат комментатору (пользователь, которого вы определили как commenter_id).

Имеет смысл для user1.comments бытьпусто, поскольку пользователь является комментатором в обоих комментариях, он не является комментируемым.user2.comments не должно быть пустым, то же самое для project.comments

Попробуйте что-то вроде этого:

class User < ApplicationRecord
  has_many :comments_done, class_name: 'Comment', inverse_of: :commenter
  has_many :comments, as: :commentable, dependent: :destroy
end

class Comment < ApplicationRecord
  belongs_to :commenter, class_name: 'User'
  belongs_to :commentable, polymorphic: true
end

(проверьте руководство, возможно, мне не хватает какой-либо опции конфигурации https://guides.rubyonrails.org/v5.2/association_basics.html#has-many-association-reference)

Теперь вы можете использовать user1.comments_done и user1.comments для комментариев, сделанных пользователем и сделанных у пользователя.

...