Beginner question - overwrite a value in a model

Hi,

i am trying to overwrite a value in a model so that the new value is beeing saved in the database instead of the one the user typed into the form.

this is my controller

class Movie < ActiveRecord::Base

  def self.creation_date=(a)     self.creation_date = "2000-01-01"   end

end

(it's only some testing for getting a feeling for the basic way ror works...)

the create form is generated by the standard scaffold :movie in my admin controller.

the new movie is beeing created but it uses the value from the form, not my new "overwritten" one.

it's obviously a simple question but iam stucked now for about 2.5 houres :frowning: shame on me...

any ideas?

Greetings,

Pascal

Hi,

i am trying to overwrite a value in a model so that the new value is beeing saved in the database instead of the one the user typed into the form.

this is my controller

I think you meant model... anyway...

class Movie < ActiveRecord::Base

before_save :fudge_creation_date

...

def fudge_creation_date    self.creation_date = Date.parse('2001-01-1') end

end

Then every time you save the record it will do what you want.

thanks (yes, model, not controller :slight_smile: ),

but why does it work in the example at "agile webdevelopement with ror" at the model http://media.pragprog.com/titles/rails2/code/depot_p/app/models/user.rb

they are setting the hashed_password value in the password=(pwd) method.

class Movie < ActiveRecord::Base

  def self.creation_date=(a)     self.creation_date = "2000-01-01"   end

end

# skipped

the new movie is beeing created but it uses the value from the form, not my new "overwritten" one.

maybe     # instance method should be without `self.` prefix!     def creation_date=(a)         self[:creation_date] = "2000-01-01"     end

?

> def self.creation_date=(a) > self.creation_date = "2000-01-01" > end

Notice that when you add self.some_method you are creating a "Class" method rather than an "Instance" method.

def password=(pwd)     @password = pwd     return if pwd.blank?     create_new_salt     self.hashed_password = User.encrypted_password(self.password, self.salt)   end

private

  def self.encrypted_password(password, salt)     string_to_hash = password + "wibble" + salt # 'wibble' makes it harder to guess     Digest::SHA1.hexdigest(string_to_hash)   end

See how the AWDWR book is defining the "password=(pwd)" method to be an instance method (no self.)

User.encrypted_password(..., ...) is defined as a Class method. Notice how they call the class method on the class not a reference to an instance.

I'm also curious why you want all your creation dates to be "2000-01-01," without any way to change it?

What are you really wanting to do here? Are you looking for behavior that time stamps record creation? If so then Rails will happily do that automatically for you. All you need to do is name your column created_on and it will automatically be set by the framework to the current date. You can also use created_at to get a full date and time, update_on/updated_at to have a time stamp update every time the record changes.

thanks for the, i think i understood this now :slight_smile:

but the thing that makes me pain in my brain is that self.hashed_password = User.encrypted...xxx asignment is to self.hashed_password and it works, the value that is written to the table at the "hashed_password" column is the one returned from user.encrypted...xxx.

it is functional equal to my new method which doesn't work (the solution with bevore_save does work but that doesn't solve the riddle the AWDWROR from book example in comparison to my little method)

def creation_date=(cd)   #same as self.hashed_password = ... // like AWDWROR team does   self.creation_date = Date.parse('2000-01-01') end

(sorry for my bad / hard to read english sentences.. :frowning: )

this is realy nice. and in fact, this was one of the things i tried to figure out. awsome!

the other thing is that i just wanted to now -if- (ok i was really shure it -is-) i can and -how- i can set values to a dynamic / static default value inside a model.

as you see, iam really new to ruby (and the mvc idear in general..) where do -you- find such things like the "created_on and it will automatically" trick? Ok, api will provide these information but a) it find it difficult to read and b) how to find s.th. you dont even know it exists? :slight_smile:

Pascal,

1) self.hashed_password = User.encrypted...xxx 2) asignment is to self.hashed_password and it works, the value

Here's the bit that you are missing. In line 1 above self.hashed_password is NOT the definition of the hashed_password method.

You do not see something like:

def self.hashed_password   ...   ... end

the hashed_password is an instance method (not a class method) that is added to the User model by Rails.

def self.authenticate(name, password)   user = self.find_by_name(name) # <=== geting a reference to an instance of User   if user     expected_password = encrypted_password(password, user.salt)     if user.hashed_password != expected_password # <=== referencing hashed_password on an instance of User       user = nil     end   end   user end