0

A controller method includes:

  @organization = Organization.find(params[:description])
  check_expiration_date(@organization)
  if @organization.update_attributes(subscription: true,
                                     actioncode: session[:actioncode_id],
                                     subs_exp_date: expiration_date)
  ...

  private
  def check_expiration_date(org)
    expiration_date = Time.zone.now + 366.days
  end

On the development server this generates the error below, referring to the line subs_exp_date: expiration_date:

undefined local variable or method `expiration_date' for #<OrganizationsController:0x007f36cd01d2a8>

Any ideas what might be causing this error? My idea was that check_expiration_date is executed first and thus sets the variable expiration_date.

Nick
  • 3,496
  • 7
  • 42
  • 96

4 Answers4

2

It should be like this:

  if @organization.update_attributes(subscription: true,
                                     actioncode: session[:actioncode_id],
                                     subs_exp_date: check_expiration_date(@organization))

If you see your code, expiration_date is a variable inside method check_expiration_date which limits its scope only to that method. Hence you cannot use variable expiration_date outside check_expiration_date.

Other way can be defining expiration date as an instance variable. Here:

def check_expiration_date(org)
    @expiration_date = Time.zone.now + 366.days
end

and then

if @organization.update_attributes(... subs_exp_date: @expiration_date)

Key here is:

Contrast the scope of a local variable with that of an instance variable: the instance variable is bound to the specific instance of the class. By binding itself to the entire object, an instance variable makes itself available to every method of the object.

shivam
  • 16,048
  • 3
  • 56
  • 71
1

Solution 1:

Change this code:

check_expiration_date(@organization)

to:

expiration_date = check_expiration_date(@organization)

Solution 2:

Change:

  def check_expiration_date(org)
    expiration_date = Time.zone.now + 366.days
  end

to:

def check_expiration_date(org)
  @expiration_date = Time.zone.now + 366.days
end

and then:

if @organization.update_attributes(subscription: true,
                                     actioncode: session[:actioncode_id],
                                     subs_exp_date: @expiration_date)

Reason: You're trying to access expiration_date, which is a local variable whose scope is limited to check_expiration_date method and hence ruby is looking for a method instead of a variable. So, you need to make it an instance variable or create a local variable from the returning object of check_expiration_date method to get it working.

Surya
  • 15,703
  • 3
  • 51
  • 74
1

It's because you set local variable expiration_date, it is visible only in current scope defined by method body. If you want to make this variable 'visible' also after method execution, you can set it instance variable:

@expiration_date = Time.zone.now + 366.days

and use it:

subs_exp_date: @expiration_date

For more info about Ruby variable scopes, you can go here:

http://www.techotopia.com/index.php/Ruby_Variable_Scope

or here:

Difference between various variables scopes in ruby

Community
  • 1
  • 1
Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
0

You are calling a local variable instead of instance variable. Its about variable scope. There are 2 options to get proper value for subs_exp_date

  1. Convert local variable to instance variable

@expiration_date = Time.zone.now + 366.days

  1. Another option to call method directly

subs_exp_date: check_expiration_date(@organization)

Arvind singh
  • 1,312
  • 15
  • 15