我有课程表和标签表。我使用has_many:through关系来关联它们,我的中间表是tags_relationship.rb
class Lesson < ActiveRecord::Base
attr_accessible :title, :desc, :content, :tag_name
belongs_to :user
has_many :tag_relationships
has_many :tags, :through => :tag_relationships
end
class Tag < ActiveRecord::Base
attr_accessible :name
has_many :tag_relationships
has_many :lessons, :through => :tag_relationships
end
在我的一个视图中,我试图创建一个虚拟属性。我有...
<div class="tags">
<%= f.label :tag_name, "Tags" %>
<%= f.text_field :tag_name, data: { autocomplete_source: tags_path} %>
</div>
但我的课程表没有该属性tag_name,所以它调用我的方法
def tag_name
????????
end
def tag_name=(name)
self.tag = Tag.find_or_initialize_by_name(name) if name.present?
end
但是我不知道该把什么放在????????。我试图在我的标签表中引用:name属性。
当时我使用了has_many和belongs_to关系。我的教训属于一个标签(这是错的),但我能够写...
tag.name
它有效。但是因为它有一个has_many:到现在为止,我不确定。我尝试使用tags.name,Lessons.tags.name等,但我似乎无法让它工作。我怎么能引用标签表名属性?谢谢
答案 0 :(得分:2)
为我糟糕的英语道歉。
当您的Lesson
属于Tag
课时,只有一个tag
,因此您的代码是正确的。但是现在Lesson
有很多Tag
s,它是集合(简单的数组)。所以,你的二传手必须更复杂:
def tag_names=(names)
names = if names.kind_of? String
names.split(',').map{|name| name.strip!; name.length > 0 ? name : nil}.compact
else
names
end
current_names = self.tags.map(&:name) # names of current tags
not_added = names - current_names # names of new tags
for_remove = current_names - names # names of tags that well be removed
# remove tags
self.tags.delete(self.tags.where(:name => for_remove))
# adding new
not_added.each do |name|
self.tags << Tag.where(:name => name).first || Tag.new(:name => name)
end
end
getter方法应该是这样的:
def tag_names
self.tags.map(&:name)
end
BTW,find_by_name
等发现者已被弃用。您必须使用where
。