简而言之,您的类缺少一个 setter(或者用 Ruby 术语来说,一个属性编写器)。有两种方法可以定义 setter 并处理将空格分隔的标签名称字符串转换为 Tag 对象并将它们持久保存在数据库中。
解决方案 1(Ryan 的解决方案)
在您的类中,使用 Ruby 的attr_writer
方法定义您的设置器,并将标签名称字符串(例如"tag1 tag2 tag3"
)转换为 Tag 对象,并在保存后回调中将它们保存在数据库中。您还需要一个 getter 将Tag
文章的对象数组转换为字符串表示形式,其中标签由空格分隔:
class Article << ActiveRecord::Base
# here we are delcaring the setter
attr_writer :tag_names
# here we are asking rails to run the assign_tags method after
# we save the Article
after_save :assign_tags
def tag_names
@tag_names || tags.map(&:name).join(' ')
end
private
def assign_tags
if @tag_names
self.tags = @tag_names.split(/\s+/).map do |name|
Tag.find_or_create_by_name(name)
end
end
end
end
解决方案2:将标签名称字符串转换为Tag
setter中的对象
class Article << ActiveRecord::Base
# notice that we are no longer using the after save callback
# instead, using :autosave => true, we are asking Rails to save
# the tags for this article when we save the article
has_many :tags, :through => :taggings, :autosave => true
# notice that we are no longer using attr_writer
# and instead we are providing our own setter
def tag_names=(names)
self.tags.clear
names.split(/\s+/).each do |name|
self.tags.build(:name => name)
end
end
def tag_names
tags.map(&:name).join(' ')
end
end