Я создал ассоциацию полиморфизма c Tagging
, принадлежащую Micropost
, а также Tag
, чтобы проиллюстрировать
РЕДАКТИРОВАНИЕ Ошибка модели тегирования
class Tagging < ApplicationRecord
belongs_to :tag, inverse_of: :taggings
belongs_to :taggable, polymorphic: true
...
...
class Tag < ApplicationRecord
has_many :taggings, as: :taggable, inverse_of: :taggable
has_many :microposts, through: :taggings, source: :taggable, source_type: 'Micropost'
end
...
class Micropost < ApplicationRecord
has_many :taggings, as: :taggable, inverse_of: :taggable
has_many :tags, through: :taggings
...
Micropost
, Tagging
и Tag
вместе прекрасно сохраняются и производятся
<Micropost id: 588, content: "<p>hi</p>", user_id: 1, created_at: "2020-04-02 10:00:34", updated_at: "2020-04-02 10:00:34", media_data: "", pics_count: nil, share_id: nil, commentable_id: nil, commentable_type: nil, gallery_id: nil>
...
<Tagging id: 8, taggable_type: "Micropost", taggable_id: 588, tag_id: 10, topic: "Travel", created_at: "2020-04-02 10:00:34", updated_at: "2020-04-02 10:00:34">
(этот тег уже существовал, поэтому нам не нужно было его создавать)
<Tag id: 10, name: "hello", created_at: "2020-04-01 08:39:36", updated_at: "2020-04-01 08:39:36">
Как вы можете видеть, наш идентификатор тегируемого источника и тип установлены правильно и наш tag_id
сохранен правильно.
Но при попытке сделать Tag.find_by_name!("hello").microposts
он возвращает пустой массив CollectionProxy
.
Чтобы показать сгенерированный sql,
tag.microposts
Micropost Load (0.4ms) SELECT "microposts".* FROM "microposts" INNER JOIN "taggings" ON "microposts"."id" = "taggings"."taggable_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND "taggings"."taggable_type" = $3 LIMIT $4 [["taggable_id", 10], ["taggable_type", "Tag"], ["taggable_type", "Micropost"], ["LIMIT", 11]]
=> <ActiveRecord::Associations::CollectionProxy []>
Он помещает tag_id
в taggable_id
, который на самом деле должен быть идентификатором микросообщения, поэтому он дает пустой массив.
Я подозреваю, что, как вы можете видеть в sql сгенерированный показывает ["taggable_type", "Tag"], ["taggable_type", "Micropost"]
, где Tag
taggable_type не должно быть, но я не знаю, как от него избавиться.
РЕДАКТИРОВАТЬ Я добавляю для ясности схему
create_table "taggings", force: :cascade do |t|
t.string "taggable_type"
t.bigint "taggable_id"
t.bigint "tag_id"
t.string "topic"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["tag_id"], name: "index_taggings_on_tag_id"
t.index ["taggable_type", "taggable_id"], name: "index_taggings_on_taggable_type_and_taggable_id"
t.index ["topic"], name: "index_taggings_on_topic"
end
create_table "tags", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["name"], name: "index_tags_on_name"
end
Так потеряно.