开发者

How do I pass a var from one model's method to another?

开发者 https://www.devze.com 2023-01-05 12:17 出处:网络
Here is my one model.. CardSignup.rb def credit_status_on_create Organization.find(self.organization_id).update_credits

Here is my one model..

CardSignup.rb

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

And here's my other model. As you can see what I wrote here is an incorrect way to pass the var

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

If it can't be done by (params[:id]), what can it be done by?

开发者_JS百科

Thanks!


Ideally the data accessible to the controller should be passed as parameter to model methods. So I advise you to see if it is possible to rewrite your code. But here are two possible solutions to your problem. I prefer the later approach as it is generic.

Approach 1: Declare a virtual attribute

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

In your controller code:

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

In your CardSignup model:

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

Update the Organization model. Note the change to your count logic.

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

Approach 2: Declare a thread local variable accessible to all models

Your controller code:

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

Update the Organization model. Note the change to your count logic.

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


Use an attr_accessor.

E.g.,

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

then you can access them as ModelName.myvar and ModelName.new.myvar respectively.


You don't say whether you're using Rails 2 or 3 but let's assume Rails 2 for this purpose (Rails 3 provides the a new DSL for constructing queries).

You could consider creating a named scope for in your Organization model as follows:

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

And then use it as follows:

def credit_status_on_create
  Organization.update_credits(self.organization_id)
end

Admittedly I don't quite understand the role of the counter in your logic but I'm sure you could craft that back into this suggestion if you adopt it.

0

精彩评论

暂无评论...
验证码 换一张
取 消