user1079369
user1079369

Reputation: 31

Rails - Model changes not being saved or preserved between controller and model

I'd appreciate any help I can get with a somewhat strange phenonemon going on in my code. The controller's create method is (roughly) as follows:

def create
  @session ||= Session.new
  @session.date = params[:date]
  @session.generate_string
  @session.save
  # etc
end

And the model:

class Session < ActiveRecord::Base # table is 'sessions' with 3  columns :id, :str, :date
  include MyHelper

  def generate_string(num_chars)
    @str ||= ""

    num_chars.to_i.times do
      @str += some_method_in_MyHelper() # method returns a string
    end
  end
end

With some logging I found out that although the generate_string is working correctly, the resulting @session (in the controller) has the date set as expected but the value of str is a blank string. Sure enough, when the .save is hit, the database is told to insert a record consisting of a blank string and the correct date.

I found this Why do my changes to model instances not get saved sometimes in Rails 3? that suggests I should be using the "self" prefix instead of @. This seems to make the code work as expected, but seems strange because I thought self.xxx referred to the class, not the class instance. I'd be grateful if anyone could clarify what's going on - thanks!

Upvotes: 1

Views: 616

Answers (2)

axsuul
axsuul

Reputation: 7480

In order to store it in the str field to be saved to the database, you need to use self.str method. I think this is what you are looking for

class Session < ActiveRecord::Base # table is 'sessions' with 3  columns :id, :str, :date
  include MyHelper

  def generate_string(num_chars)
    str = ""

    num_chars.to_i.times do
      str += some_method_in_MyHelper() # method returns a string
    end

    self.str = str # store it in attribute to be saved into db
  end
end

Notice I removed the instance variable @str and changed it to local variable str instead because it seems like you want to generate a new string everytime this method is called? Also, this variable caching is useless

@session ||= Session.new

because instance variables only stick around for a single request. It should be

@session = Session.new

Upvotes: 0

Dave Newton
Dave Newton

Reputation: 160181

self refers to the instance when used inside an instance method. It refers to the class outside an instance method, when it (self) is the class that's being defined.

@ is an instance variable, which is different than an ActiveRecord column.

Upvotes: 1

Related Questions