2011-02-24 5 views
3

Ma configuration: Rails 2.3.10, Ruby 1.8.7Accès attribut virtuel à partir JSON

Je l'ai expérimenté, sans succès, en essayant d'accéder à un attribut virtuel dans un modèle à partir d'un appel JSON. Disons que je les modèles suivants et le code du contrôleur

class Product 
name, 
description, 
price, 
attr_accessor :discounted_price 
end 

class Price 
discount 
end 

class ProductsController 
def show 
    @product = Product.find(params[:id]) 
    respond_to do |format| 
    format.html # show.html.erb 
    format.json { render :json => @product }          
    end 
end 
end 

Ce que je veux est d'avoir la sortie JSON comprennent également Product.discounted_price qui est calculé en temps réel pour chaque appel, soit discounted_price = Price.discount * Produit .prix. Y a-t-il un moyen d'accomplir cela?

SOLUTION: Avec l'aide initiale de dmarkow, j'ai tout compris, mon scénario réel est plus complexe que l'exemple ci-dessus. Je peux faire quelque chose comme ça, dans le modèle de produit, ajoutez une méthode getter

def discounted_price 
...# do the calculation here 
end 

Dans l'appel JSON faire ce

store = Store.find(1) 
store.as_json(:include => :products, :methods => :discounted_price) 
+0

Pourquoi avez-vous le prix comme une autre classe? – s84

+0

Ok, mauvais exemple mais pour le bien de la discussion, supposons que j'ai besoin de faire ça :) – Bob

Répondre

25

Vous pouvez exécuter to_json avec un paramètre :methods pour inclure le résultat de ces méthode (s).

render :json => @product.to_json(:methods => :discounted_price) 
+0

Merci, ça marche mais mon scénario actuel est plus compliqué. Disons que le produit appartient au magasin et le magasin a beaucoup de produits. Je dois retourner json avec @ store.to_json (: include =>: produits) et être capable de définir le product.discounted_price pendant l'appel. Des suggestions sur la façon de faire cela? – Bob

+0

Peu importe, je l'ai compris. Je peux faire quelque chose comme ça, dans le modèle de produit, ajoutez une méthode def discounted_price ... # Faites le calcul ici fin Dans l'appel JSON faire ce magasin = Store.find (1) store.as_json (: include => produits,: methods =>: discounted_price) – Bob