Rails的HABTM fields_for - 检查是否具有相同名称的记录已经存在(Rails

2019-09-29 20:01发布

我有模型“片断”和“标签”之间的HABTM-关系。 目前,当我保存一个片段与几个标签,每个标签被保存为一个新的记录。

现在我想检查是否具有相同名称的标签已经存在,如果that's的情况下,我不希望有一个新的记录,只有在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 %>

Answer 1:

好吧,i'm不耐烦......过了一会儿,我发现我工作的解决方案。 我不知道这是不是最好的方式,但我想,虽然表现出来。

我不得不修改瑞安贝茨Railscast的解决方案“自动完成协会” ,它可以处理一个belongs_to的关联得到它与HABTM工作。

在我的片段形式是命名一个tag_names加新文本字段,这需要一个逗号分隔的标签列表。

像瑞安,我用虚拟属性来获取和设置标签。 我认为剩下的就是不言自明的,所以here's代码。

查看“_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

这仅仅是基本的代码,不能很好地测试和需要改进,但它似乎可行,i'm高兴能有一个解决办法!



文章来源: Rails HABTM fields_for – check if record with same name already exists