2 votes

Rails string array et PostgreSQL

J'ai un modèle Rails nommé Container avec une colonne nommée products . Il s'agit d'un tableau de chaînes tel que supporté par Postgres et la gemme 'postgres_ext'.

La partie pertinente de la GEMFILE est :

gem 'rails', '3.2.9'
gem 'pg'
gem 'postgres_ext'
gem 'activerecord-postgres-hstore', git: 'git://github.com/engageis/activerecord-postgres-hstore.git'

La partie pertinente de la migration est :

 t.string :products, array: true

J'écris une méthode publique dans mon Container qui ajoute des produits à ce tableau. La méthode ressemble à ceci :

 attr_accessible :products

 def add_to_products(product)

  if products.blank? || products.size == 0 ## product array is either uninstantiated or blank
    products = [product.id]
  else  

    unless products.include? product.id
      products << product.id
    end
  end
end

Voici les résultats dans irb/console :

pry(main)> c = Container.first
=> #<Container id: "2765cc19-98f8-4e42-a1be-538788424ec7", name:....
pry(main)> p = Product.first
=> #<Product id: "319a25ae-87fe-4769-a9de-1a8e0db9e84f", name: ....
pry(main)> c.add_to_products(product)
pry(main)> c.products
=> nil
pry(main)> c.products= [] << "319a25ae-87fe-4769-a9de-1a8e0db9e84f"
pry(main)> c.products
=> ["319a25ae-87fe-4769-a9de-1a8e0db9e84f"]

Je me gratte la tête pour comprendre ce qui ne va pas dans le add_to_products méthode. Quelqu'un peut-il m'éclairer sur cette situation étrange ? Pourquoi la valeur n'est-elle pas définie lorsque je la fais passer par cette méthode ?

5voto

Dan McClain Points 7036

Cette question découle en fait de l'utilisation de << . Rails ne suit pas les modifications en place des attributs ( voir ce numéro ). J'expose dans les notes d'utilisation que vous voulez éviter le << lors de l'utilisation de tableaux, car les rails ne verront pas ce changement, il causera en fait des problèmes avec les valeurs par défaut.

Cela peut également être vu en vérifiant le products_changed? l'état. Il sera faux lorsque vous utiliserez << .

2voto

Casper Points 15645

Cela a à voir avec le fait qu'en Ruby les affectations créent des variables locales à moins que vous ne déclariez explicitement le récepteur, ce qui est self dans ce cas. Donc :

products = [product.id]

...va créer une variable locale nommée products . Considérant :

self.products = [product.id]

...est ce que vous recherchez vraiment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X