模型“Snippets”和“Tags”之间存在HABTM关系。目前,当我保存带有几个标签的代码段时,每个标签都会保存为新记录。
现在我想检查一个具有相同名称的标签是否已经存在,如果是这样的话,我不想要一条新记录,只需要在现有记录的snippets_tags中输入一个条目。
我该怎么做?
snippet.rb:
class Snippet < ActiveRecord::Base
accepts_nested_attributes_for :tags, :allow_destroy => true, :reject_if => lambda { |a| a.values.all?(&:blank?) }
...
end
_snippet.html.erb:
<% f.fields_for :tags do |tag_form| %>
<span class="fields">
<%= tag_form.text_field :name, :class => 'tag' %>
<%= tag_form.hidden_field :_destroy %>
</span>
<% end %>
答案 0 :(得分:0)
好的,我很不耐烦......过了一会儿,我发现了一个适合我的解决方案。我不知道这是不是最好的方式,但我想展示它。
我必须修改Ryan Bates Railscast "Auto-Complete Association"的解决方案,该解决方案处理belongs_to-association以使其与HABTM一起使用。
在我的代码段表单中是一个名为tag_names的新文本字段,它需要以逗号分隔的标记列表。
像Ryan一样,我使用虚拟属性来获取和设置标签。我认为其余部分是不言自明的,所以这是代码。
查看“_snippet.html.erb”
<div class="float tags">
<%= f.label :tag_names, "Tags" %>
<%= f.text_field :tag_names %>
</div>
模型“snippet.rb”:
def tag_names
# Get all related Tags as comma-separated list
tag_list = []
tags.each do |tag|
tag_list << tag.name
end
tag_list.join(', ')
end
def tag_names=(names)
# Delete tag-relations
self.tags.delete_all
# Split comma-separated list
names = names.split(', ')
# Run through each tag
names.each do |name|
tag = Tag.find_by_name(name)
if tag
# If the tag already exists, create only join-model
self.tags << tag
else
# New tag, save it and create join-model
tag = self.tags.new(:name => name)
if tag.save
self.tags << tag
end
end
end
end
这只是基本代码,没有经过充分测试,需要改进,但看起来很有效,我很乐意有一个解决方案!