Когда я передаю объект комментария с параметрами в объект Notification.create (), я получаю ActiveRecord :: AssociationTypeMismatch для пользователя.Это говорит о том, что я передал экземпляр Integer (который, возможно, является идентификатором пользователя) вместо самого объекта User.Я не знаю, как мне подойти к получению объекта пользователя из объекта комментария и передаче его в столбец получателя.Я использую камень под названием acts_as_commentable_with_threading .Как передать правильный экземпляр объекта User в Уведомление?
Я попытался получить пользователя, используя цепочку комментариев через comment.commentable.user.Который вернул целевого пользователя.Но по какой-то причине он заявляет, что я не могу использовать объект, так как это тип Integer, а не User.Ниже приведена ошибка.
Comment Load (1.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."id" = $1 LIMIT $2 FOR UPDATE [["id", 16], ["LIMIT", 1]]
Comment Create (2.0ms) INSERT INTO "comments" ("commentable_id", "commentable_type", "body", "user_id", "lft", "rgt", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["commentable_id", 3], ["commentable_type", "Post"], ["body", "Damn"], ["user_id", 2], ["lft", 21], ["rgt", 22], ["created_at", "2019-02-04 18:23:47.285528"], ["updated_at", "2019-02-04 18:23:47.285528"]]
(1.0ms) COMMIT
Redirected to http://127.0.0.1:3000/posts/qQ7JeRcQxGXg
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 3], ["LIMIT", 1]]
Completed 500 Internal Server Error in 6196ms (ActiveRecord: 1466.1ms)
ActiveRecord::AssociationTypeMismatch (User(#211252000) expected, got 2 which is an instance of Integer(#3523260)):
app/controllers/comments_controller.rb:17:in `create'
Processing by ExceptionHandler::ExceptionsController#show as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"KnLViXrCG/67gbUFTQjFMq6eIt7AKvjG4dRgD0JSoPOCOfHqU0n0lVB9l3+lyAc0B+G3mgZ6dv8cG0v9LTvPuw==", "comment"=>{"commentable_id"=>"3", "commentable_type"=>"Post", "body"=>"Damn"}, "commit"=>"Comment"}
Completed 500 Internal Server Error in 285ms (ActiveRecord: 0.0ms)
comments_controller.rb
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
commentable = commentable_type.constantize.find(commentable_id)
@comment = Comment.build_from(commentable, current_user.id, body)
respond_to do |format|
if @comment.save
make_child_comment
format.html {redirect_back(fallback_location: post_path(@comment))}
format.js
else
format.html {render :action => :new}
end
end
Notification.create(recipient: @comment.commentable.user, actor: current_user.id, action: "commented on your Post", notifiable: @comment.commentable.id, content: @comment.body.truncate(50).to_s)
#GenericCommentNotificationJob.perform_later(@comment.commentable.user, current_user.id, @comment, body)
end
def destroy
@comment = Comment.find_by_id params[:id]
respond_to do |format|
if @comment.destroy
format.html {redirect_to @comment.commentable}
else
format.html {redirect_to @comment.commentable, notice: t('error')}
end
end
end
private
def comment_params
params.require(:comment).permit(:body, :commentable_id, :commentable_type, :comment_id)
end
def commentable_type
comment_params[:commentable_type]
end
def commentable_id
comment_params[:commentable_id]
end
def comment_id
comment_params[:comment_id]
end
def body
comment_params[:body]
end
def make_child_comment
return "" if comment_id.blank?
parent_comment = Comment.find(comment_id)
@comment.move_to_child_of(parent_comment)
end
end
схема комментариев
create_table "comments", force: :cascade do |t|
t.integer "commentable_id"
t.string "commentable_type"
t.string "title"
t.text "body"
t.string "subject"
t.integer "user_id", null: false
t.integer "parent_id"
t.integer "lft"
t.integer "rgt"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "post_id"
t.index ["post_id"], name: "index_comments_on_post_id"
t.index ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type"
t.index ["user_id"], name: "index_comments_on_user_id"
end
comment.rb
class Comment < ActiveRecord::Base
acts_as_nested_set :scope => [:commentable_id, :commentable_type]
validates :body, :presence => true
validates :user, :presence => true
# NOTE: install the acts_as_votable plugin if you
# want user to like on the quality of comments.
acts_as_votable
belongs_to :commentable, :polymorphic => true
# NOTE: Comments belong to a user
belongs_to :user
# Helper class method that allows you to build a comments
# by passing a commentable object, a user_id, and comments text
# example in readme
def self.build_from(obj, user_id, comment)
new \
:commentable => obj,
:body => comment,
:user_id => user_id
end
#helper method to check if a comments has children
def has_children?
self.children.any?
end
# Helper class method to lookup all comments assigned
# to all commentable types for a given user.
scope :find_comments_by_user, lambda {|user|
where(:user_id => user.id).order('created_at DESC')
}
# Helper class method to look up all comments for
# commentable class name and commentable id.
scope :find_comments_for_commentable, lambda {|commentable_str, commentable_id|
where(:commentable_type => commentable_str.to_s, :commentable_id => commentable_id).order('created_at DESC')
}
# Helper class method to look up a commentable object
# given the commentable class name and id
def self.find_commentable(commentable_str, commentable_id)
commentable_str.constantize.find(commentable_id)
end
end
messages.rb
class Notification < ApplicationRecord
belongs_to :recipient, class_name: "User"
belongs_to :actor, class_name: "User"
belongs_to :notifiable, polymorphic: true
scope :unread, -> {where(read_at: nil)}
end
схема уведомлений
create_table "notifications", force: :cascade do |t|
t.integer "recipient_id"
t.integer "actor_id"
t.datetime "read_at"
t.string "action"
t.integer "notifiable_id"
t.string "notifiable_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "content"
end
Фактические результаты : Когда пользователь пытается создать комментарий, уведомление не может создать себя из-за активного несоответствия типов записей для пользовательского объекта.
Ожидаемые результаты: пользователь создает комментарий, а затем уведомление создается после успешной фиксации комментария.