つまり、クラスにセッター(またはRuby lingoでは属性ライター)がありません。セッターを定義し、スペースで区切られたタグ名の文字列をタグオブジェクトに変換してデータベースに保持する方法は2つあります。
解決策1(ライアンの解決策)
クラスで、Rubyのattr_writer
メソッドを使用してセッターを定義し、タグ名の文字列(たとえば)をTagオブジェクトに変換し、"tag1 tag2 tag3"
保存後のコールバックでデータベースに保存します。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
セッター内のオブジェクトに変換する
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