非常に奇妙なレールの動作をデバッグするのに1時間を費やしました。 考える:Railsモデルのaffords HABTMの動作に 'インクルード'位置があるのはなぜですか?
アプリ/モデル/ user.rb
class User < ApplicationRecord
...
has_many :images
has_many :videos
...
has_many :tags
...
end
アプリ/モデル/ image.rb
class Image < ApplicationRecord
...
belongs_to :user
...
has_and_belongs_to_many :tags
...
include TagsFunctions
...
end
アプリ/モデル/ video.rb
class Video < ApplicationRecord
...
include TagsFunctions
...
belongs_to :user
...
has_and_belongs_to_many :tags
...
end
アプリ/モデル/tag.rb
class Tag < ApplicationRecord
belongs_to :user
validates :text, uniqueness: {scope: :user}, presence: true
before_create :set_code
def set_code
return if self[:code].present?
loop do
self[:code] = [*'A'..'Z'].sample(8).join
break if Tag.find_by(code: self[:code]).nil?
end
end
end
アプリ/モデル/懸念/ tags_functions.rb
module TagsFunctions
extend ActiveSupport::Concern
# hack for new models
included do
attr_accessor :tags_after_creation
after_create -> { self.tags_string = tags_after_creation if tags_after_creation.present? }
end
def tags_string
tags.pluck(:text).join(',')
end
def tags_string=(value)
unless user
@tags_after_creation = value
return
end
@tags_after_creation = ''
self.tags = []
value.to_s.split(',').map(&:strip).each do |tag_text|
tag = user.tags.find_or_create_by(text: tag_text)
self.tags << tag
end
end
end
私は、このようなコードを実行した場合:
user = User.first
tags_string = 'test'
image = user.images.create(tags_string: tags_string)
video = user.videos.create(tags_string: tags_string)
それはで1つのアイテムを与えますimage.tags
ですが、重複する項目は2つあります。video.tags
しかし、我々はこのようコードを変更した場合:
user = User.first
tags_string = 'test'
image = Image.create(user: user, tags_string: tags_string)
video = Video.create(user: user, tags_string: tags_string)
すべてが正常に動作し、画像や映像
、さらに1個のタグ1個のタグ... 我々は以下のinclude TagsFunctions
を移動した場合has_and_belongs_to_many :tags
、video.rb
ファイルでは、両方のコード例が正常に動作します。
私はレールをかなりよく知っていると思っていましたが、この動作は私にとっては本当に不明です。
Railsのバージョン:5.1.1
私は質問を編集し、tag.rbのコンテンツを追加しました。 私にとって奇妙なのは、画像とビデオの2つの線が等しいことです。 私のアプリケーションをデバッグすると、habtmの関連付けが2つの異なる場所で2回追加されていることに気付きました。最初のレコードは、 'self.tags << tag'行が実行されているときに追加され、ビデオレコードが保存されているときに2番目のレコードが追加されています。 –
私の英語のために申し訳ありません:) と言って_タグの関連付けを避けるのが良いかもしれません._あなたはhas_many:タグを別のものにリネームする必要がありますか? –