Answer the question
In order to leave comments, you need to log in
Why does the behavior of the HABTM association depend on the position of include in the model?
Hello.
I've spent the last hour debugging a very strange behavior of rails.
There are following
app/models/user.rb models
class User < ApplicationRecord
...
has_many :images
has_many :videos
...
has_many :tags
...
end
class Image < ApplicationRecord
...
belongs_to :user
...
has_and_belongs_to_many :tags
...
include TagsFunctions
...
end
class Video < ApplicationRecord
...
include TagsFunctions
...
belongs_to :user
...
has_and_belongs_to_many :tags
...
end
module TagsFunctions
extend ActiveSupport::Concern
# хак для заполнения тэгов у вновь создаваемых моделей
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)
video.tags
we have two identical (duplicate) tags. image.tags
- one tag. user = User.first
tags_string = 'test'
image = Image.create(user: user, tags_string: tags_string)
video = Video.create(user: user, tags_string: tags_string)
video.rb
move include TagsFunctions
after , then everything starts working correctly with the first version of the code.
I thought I knew rails well, but this behavior baffles me.
Rails version: 5.1.1
Who can explain this behaviour? has_and_belongs_to_many :tags
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question