1

J'ai une relation HABTM entre les modèles "Snippets" et "Tags". Actuellement, lorsque je sauvegarde un extrait avec quelques balises, chaque balise est enregistrée en tant que nouvel enregistrement.Rails HABTM fields_for - vérifier si l'enregistrement portant le même nom existe déjà

Maintenant je veux vérifier si une étiquette avec le même nom existe déjà et si c'est le cas, je ne veux pas un nouvel enregistrement, seulement une entrée dans snippets_tags à l'enregistrement existant.

Comment puis-je faire cela?

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

Je suis également bloqué avec cela, s'attendant à ce qu'il y ait une réponse, mais pas de vote, pas de favori, et pas de réponse (à part une de l'auteur lui-même) depuis 3,5 ans !? – Quv

Répondre

0

Ok, impatient ... je suis après un certain temps je l'ai trouvé une solution qui fonctionne pour moi. Je ne sais pas si c'est le meilleur moyen, mais je veux le montrer cependant.

J'ai dû modifier la solution de Ryan Bates Railscast "Auto-Complete Association", qui gère une appartenance à l'association pour qu'il fonctionne avec HABTM.

Dans mon snippet-form est un nouveau champ de texte nommé tag_names, qui attend une liste de balises séparées par des virgules.

Comme Ryan, j'utilise un attribut virtuel pour obtenir et définir les balises. Je pense que le reste est explicite, alors voici le code.

Voir "_snippet.html.erb"

<div class="float tags"> 
    <%= f.label :tag_names, "Tags" %> 
    <%= f.text_field :tag_names %> 
</div> 

Modèle "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 

Ceci est juste le code de base, pas très bien testé et dans le besoin d'amélioration, mais cela fonctionne apparemment et je suis heureux d'avoir une solution!