Overriding new or create for a model


#1

I have a model where I need to calculate one of the fields when I create
a new instance. It seems to me that I should do this in the model code
and that I should override the new and/or create methods.

Is this the right approach and, if so, how can I execute the existing
method but add on my calculation?

I want something like:

def create
-Do the original create first-
field = calculated_value
save
self
end

How do I call the original create method and use the parameters passed?
Also, should I be overriding new or create or both?

Thanks for any help.

Julian


#2

How do I call the original create method and use the parameters passed?
Also, should I be overriding new or create or both?

I’m new at this, but I think you’ll want to take a lot at callbacks.

http://api.rubyonrails.com/classes/ActiveRecord/Callbacks.html


#3

def test(parameters)
super
end

The super method calls the original method (eg. test) in the
superclass and passes the same parameters as the originally invoked
method.

-John


John S.
Computing Staff - Webmaster
Kavli Institute for Theoretical Physics
University of California, Santa Barbara
removed_email_address@domain.invalid
(805) 893-6307


#4

Neither :slight_smile:

Override initialize. Create calls new internally, and new calls
initialize.

class Person < ActiveRecord::Base
alias :old_initialize :initialize
def initialize(attributes = nil)
old_initialize(attributes)
# Do whatever you want in here.
end
end

Note that your customised initialize method will be called for any
Person
object that is instantiated.

-Jonathan.


#5

Also, should I be overriding new or create or both?
overriding new should be enough since create calls new anyway.

  # File vendor/rails/activerecord/lib/active_record/base.rb,

line 443
443: def create(attributes = nil)
444: if attributes.is_a?(Array)
445: attributes.collect { |attr| create(attr) }
446: else
447: attributes.reverse_merge!(scope(:create)) if scoped?
(:create)
448:
449: object = new(attributes)
450: object.save
451: object
452: end
453: end

-John


John S.
Computing Staff - Webmaster
Kavli Institute for Theoretical Physics
University of California, Santa Barbara
removed_email_address@domain.invalid
(805) 893-6307


#6

Jonathan V. wrote:

Neither :slight_smile:

Override initialize. Create calls new internally, and new calls
initialize.

Thanks Jonathan. That’s just what I needed.

Julian


#7

Please help me understand this.

I would thing that you would be able to simply implement your own
initialize
method and perform a super inside, like this:

class Person < ActiveRecord::Base
def initialize(*args)
super(*args)
# Do whatever you want in here.
end
end

Yet this is not working for me.


#8

Nevermind. With additional searching I found an explanation at:

http://www.ruby-forum.com/topic/17456#11446

And this helpful blog entry:

http://blog.teksol.info/articles/2005/12/14/setting-default-values-in-models