2015-07-13 1 views
1

J'ai trois modèles "Entrée", "Mécanisme" et "Sortie".Désignation automatique des objets basée sur des associations avec d'autres modèles

Mécanisme 'has_one': entrée et 'has_one': sortie. Je veux qu'il fasse en sorte qu'un objet Mécanisme ait l'attribut de nom "L'effet de l'entrée X sur la sortie Y".

Voici ce que j'ai essayé:

class Mechanism 
    include Neo4j::ActiveNode 
    property :name, default: 'NewMechanism#{self.class.count}' 
    has_one :in, :input, class_name: 'Input' 
    has_one :out, :output, class_name: 'Output' 
    after_create :name_mechanism 
    def name_mechanism 
    self.update_attributes(name: "Effect of #{self.input.name} on #{self.output.name}") 
    end 
end 

Mais quand j'initialise un objet dans la console, je reçois l'erreur

NoMethodError: undefined method `name' for nil:NilClass from app/models/mechanism.rb:12:in 'name_mechanism'

Alors oui j'utilise Neo4j comme base de données, mais je Je soupçonne que ce n'est pas un problème néo4j, mais plutôt ma faible compréhension des rappels dans Rails. Aucun conseil?

Répondre

2

Votre code suppose que chaque mécanisme aura toujours une entrée et une sortie associées. Vous devez répondre à des situations où ce n'est pas le cas. Vous pourriez faire quelque chose comme ça

class Mechanism 
    include Neo4j::ActiveNode 
    property :name, default: 'NewMechanism#{self.class.count}' 
    has_one :in, :input, class_name: 'Input' 
    has_one :out, :output, class_name: 'Output' 
    before_create :name_mechanism 

    def name_mechanism 
    if self.name.blank? 
     self.name = self.default_name 
    end 
    end 

    def default_name 
    "Effect of #{self.input ? self.input.name : "<input not set>"} on #{self.output ? self.output.name : "<output not set>"}" 
    end 

end 

note que j'ai changé le rappel à un before_create puisque c'est un meilleur endroit pour définir un nom par défaut. Notez aussi que name_mechanism garde le nom s'il a déjà un nom non vide.

2

Résolu. Cela suppose que les objets Input et Output existent avant de créer un mécanisme qui lie les deux.

class Mechanism 
    include Neo4j::ActiveNode 
    property :name, default: 'New Mechanism #{self.class.count}' 
    has_one :in, :input, class_name: 'Input' 
    has_one :out, :output, class_name: 'Output' 
    after_save :name_mechanism 
    def name_mechanism 
    unless (self.input.nil?) || (self.output.nil?) 
     self.name = "Effect of #{self.input.name} on #{self.output.name}" 
    end 
    end 
end 

plats à emporter clés: Lorsque vous utilisez Neo4j, callbacks sont des méthodes sur ActiveNode, non ActiveRecord. Ils ont les mêmes noms et usages que les callbacks d'ActiveRecord, mais comme le "cycle de vie de l'objet" peut être un peu différent dans Neo4j, l'utilisation typique des callbacks peut ne pas toujours s'appliquer.

+1

Je pense que l'affacturage de Max vaut le coup d'oeil, mais je suis également curieux de connaître le problème sous-jacent. À quoi ressemblent vos instructions de création/sauvegarde? Si vous créez, par exemple, et spécifiez l'entrée et la sortie à ce moment-là, alors il y a peut-être un argument pour que 'after_save' arrive après toutes les créations de relations. Je pense qu'il pourrait être utile d'ajouter un problème au repo 'neo4j': github.com/neo4jrb/neo4j/issues/new –