2010-06-30 5 views
0

Voici mon seul modèle ..Comment passer une variable d'une méthode d'un modèle à une autre?

CardSignup.rb

def credit_status_on_create 
    Organization.find(self.organization_id).update_credits 
end 

Et voici mon autre modèle. Comme vous pouvez le voir ce que j'ai écrit ici est une mauvaise façon de passer le var

def update_credits 
    @organization = Organization.find(params[:id]) 
    credit_count = @organization.card_signups.select { |c| c.credit_status == true}.count 
end 

Si elle ne peut pas être fait par (params [: id]), que peut-il être fait par?

Merci!

Répondre

1

Idéalement, les données accessibles au contrôleur doivent être transmises en tant que paramètre aux méthodes du modèle. Je vous conseille donc de voir s'il est possible de réécrire votre code. Mais voici deux solutions possibles à votre problème. Je préfère l'approche plus tardive car elle est générique.

Approche 1: Déclarer un attribut virtuel

class CardSignup 
attr_accessor call_context 
def call_context 
    @call_context || {} 
end 
end 

Dans votre code du contrôleur:

def create 
    cs = CardSignup.new(...) 
    cs.call_context = params 
    if cs.save 
    # success 
    else 
    # error 
    end 
end 

Dans votre modèle CardSignup:

def credit_status_on_create 
    Organization.find(self.organization_id).update_credits(call_context) 
end 

Mise à jour du modèle Organisation. Notez le changement à votre logique de compte.

def update_credits 
    @organization = Organization.find(call_context[:id]) 
    credit_count = @organization.card_signups.count(:conditions => 
        {:credit_status => true}) 
end 

Approche 2: Déclarez une variable locale fil accessible à tous les modèles

Votre code de commande:

def create 
    Thread.local[:call_context] = params 
    cs = CardSignup.new(...) 
    if cs.save 
    # success 
    else 
    # error 
    end 
end 

Mise à jour du modèle Organization. Notez le changement à votre logique de compte.

def update_credits 
    @organization = Organization.find((Thread.local[:call_context] ||{})[:id]) 
    credit_count = @organization.card_signups.count(:conditions => 
        {:credit_status => true}) 
end 
0

Utilisez un attr_accessor.

Par ex,

class << self 
    @myvar = "something for all instances of model" 
    attr_accessor :myvar 
end 
@myothervar = "something for initialized instances" 
attr_accessor :myothervar 

alors vous pouvez y accéder en ModelName.myvar et ModelName.new.myvar respectivement.

+0

Cette solution n'est pas sûre pour les threads. –

+0

Sauf s'il utilise JRuby, il ne sera pas vraiment multithread de toute façon. –

0

Vous ne dites pas si vous utilisez Rails 2 ou 3 mais assumons Rails 2 à cet effet (Rails 3 fournit un nouveau DSL pour la construction de requêtes).

Vous pourriez envisager de créer un champ nommé dans votre modèle d'organisation comme suit:

named_scope :update_credits, 
      lambda { |id| { :include => :card_signup, :conditions => [ "id = ? AND card_signups.credit_status = TRUE", id ] } } 

Et puis utilisez comme suit:

def credit_status_on_create 
    Organization.update_credits(self.organization_id) 
end 

Il est vrai que je ne comprends pas tout à fait le rôle de le compteur dans votre logique, mais je suis sûr que vous pourriez réécrire cela dans cette suggestion si vous l'adoptez.

Questions connexes