6
votes

RUBY ON RAILS Attribut Dynamic Champs de la DB à l'aide de méthodes_missing Problèmes

Alors, pensais que j'avais ce travail la nuit dernière, je pouvais l'asserrer. Maintenant, il n'y a pas de travail, et je pense qu'il est temps de demander de l'aide.

im définissant des champs dynamiques dans la base de données, Semi EAV style, et laissez simplement l'état actuellement, je ne me soucie pas d'entendre vos opinions sur la question de savoir si EAV est un bon Idée ou non :) p>

De toute façon je le fais un peu différemment que ive fait dans le passé, en gros, lorsqu'un attribut (ou un champ), est ajouté, je crée une colonne Ajouter à une migration de table des attributs particuliers et exécutez Il (ou un retirez-le) - de toute façon, car il existe une couche de catégorie assis au milieu qui est la relation directe où tous les attributs sont définis, je ne peux pas utiliser le nom d'attribut réel en tant que nom de colonne, car les attributs sont des attributs. spécifique. p>

Donc, si cela vous aide à visualiser p>

    def method_missing(method, *args)

      return if self.project_category.blank?

      puts "Sorry, I don't have #{method}, let me try to find a dynamic one."
      puts "let me try to find a dynamic one"

      keys = self.project_category.dynamic_fields.collect {|o| o.name.to_sym }

      if keys.include?(method)
        field = self.project_category.dynamic_fields.select { |field| field.name.to_sym == method.to_sym && field.project_category.id == self.project_category.id }.first
        fields = self.project_category.dynamic_field_values.select {|field| field.name.to_sym == method }
        self.project_category_field_value.send("field_#{field.id}".to_sym, *args)
      end

    end


0 commentaires

3 Réponses :


2
votes

C'est une programmation sérieusement intense pour se passer dans la méthode méthod_missing code>. Ce que vous devriez avoir, c'est quelque chose de plus comme ceci: xxx pré>

Vous pouvez alors essayer de casser cela en deux parties. La première consiste à créer une méthode qui décide s'il peut gérer un appel avec un nom donné, ici dynamic_attribute_method_for code>, et la seconde est la méthode réelle en question. Le travail du premier est de s'assurer que ces derniers fonctionne au moment où il est appelé, éventuellement à l'aide de définir_method code> pour éviter de passer à nouveau à nouveau la prochaine fois que vous accédez au même nom de la méthode. p>

Cette méthode pourrait ressembler à ceci: P>

def dynamic_attributes
  @dynamic_attributes ||= DynamicAccessor.new(self)
end


1 commentaires

Merci pour la réponse, je n'ai pas pu le faire fonctionner seul via le code ci-dessus, mais j'en ai utilisé une partie de cela dans le refactoring, donc j'ai accepté comme réponse



0
votes

Pour quelqu'un d'autre essayant de faire le même genre de chose, mais avoir des problèmes, les problèmes / solutions autant que je puisse comprendre étaient les suivants:

1) Bien que je pensais que le code suivant fonctionnerait: P>

self.send(:define_method, name)


0 commentaires

3
votes

Vous pouvez regarder ma présentation où j'ai décrit comment déléguer des méthodes aux modèles associés EAV avec ActionCord

pour Exemple Nous utilisons sti forts> pour nos modèles forts> produits forts> et nous avons associé attribut strong> modèles pour eux. P>

Au début, nous créons le Abstract Attribut STRAND> MODÈLE P>

SimpleProduct.create(code: '#1', price: 2.75, quantity: 5, active: true)
product = SimpleProduct.find(1)
product.code     # "#1"
product.price    # 2.75
product.quantity # 5
product.active?  # true

product.price_changed? # false
product.price = 3.50
product.code_changed?  # true
product.code_was       # 2.75


1 commentaires

Merci d'avoir partagé. J'essaie juste d'obtenir un modèle EAV jusqu'à ce que cela a été utile.