Method not receiving object values

Hi everyone,

I’m having a weird issue

I have a Study model that has several fields, but to mention a few (or
that ones that I’m having troubles with) are

  • profesion_related
  • profesion_name

I have this in my controller

def create
@study = Study.new(params[:study])
respond_to do |format|
if @study.save
#code here
else
#more code here
end
end
end

and in my model

class Study < AR…
#there are other attr_accessible but just wanted to show this
attr_accessible :profesion_related
attr_accessor :profesion_related

def profesion_related=(id)
profesion_parent = Profesion.find(id)
######below here the last attribute is the one that is empty
new_profesion = Profesion.create({m_code: profesion_parent.m_code,
g_code: profesion_parent.g_code, name: self.profesion_name})
end

end

I’m getting an error there because self.profesion_name is empty, but
in my log I see that it’s being sent and also if I put in my create
action

   @study = Study.new(params[:study]

-> puts @study.to_yaml
respond_to

I can see that the object @study has every single attribute filled,
but inside the profesion_related method in my model, the
self.profesion_name is empty

What could be wrong with this?
Hope someone can help me

Thanks in advance

It’s possible that the profesion_name is not set yet – you might want
to
consider creating the Profesion model in a before_save callback. I
suspect
there are some issues with how this is model, but hopeful this
suggestion
will get you moving foward.

Cheers, Nicholas

On Jan 2, 10:42pm, JavierQQ [email protected] wrote:

Hi everyone,

I can see that the object @study has every single attribute filled,
but inside the profesion_related method in my model, the
self.profesion_name is empty

What could be wrong with this?
Hope someone can help

An activerecord object’s initialize method basically does

attributes.each do |attr_name, value |
send(“#{attr_name}=”, value)
end

So at some point it will call self.profession_name = and at some point
it will call self.profession_related but there’s no particular order
that is is guaranteed to happen in (on ruby 1.9 I wouldn’t be
surprised if it was the order of the fields on the page)

You might want to consider building the profession either outside of
new entirely or in a callback. It’s also possible that how you’ve
modelled it is making it more complicated than it has to be but it’s
hard to tell that from here.

Fred

No, there isn’t. Callbacks are your best bet.


Dheeraj K.

Hi guys,

Thanks both for the reply, I know it could be done by using a callback
but
there are more code inside that method.
I’m using profesion_related as mentioned here
#16 Virtual Attributes - RailsCasts (as well as other
code
inside that method)

On Thu, Jan 3, 2013 at 3:22 AM, Frederick C.
<[email protected]

wrote:

surprised if it was the order of the fields on the page)

Indeed, I was trying so many times that I was wondering if it may have
an
special order of setting the values and it may be doing that method
BEFORE
filling the other values.
It seems that the best way to avoid this is by doing a callback (in that
case I will have to change more code :/).

Is a way of telling AR to use that method after every other?

Thanks

Javier

IMHO AR lists the attributes as it receives them from schema and any
virtual attributes from the model. This is because attributes is a hash,
and Ruby 1.9 maintains the key order in a hash.

If your code depends on the order of attributes defined, it’s definitely
a smell.


Dheeraj K.

On Thu, Jan 3, 2013 at 8:52 AM, Dheeraj K.
[email protected]wrote:

No, there isn’t. Callbacks are your best bet.

In the end I made a before_validation callback and inside that I’m using
the virtual attribute, but I’m still wondering how AR order the list of
attributes

I started here

but
I’m not sure where should I go next. Hope somebody can guide me

Thanks

Javier

On Thu, Jan 3, 2013 at 12:02 PM, Javier Q. [email protected]
wrote:

virtual attribute, but I’m still wondering how AR order the list of
attributes

I started here

but I’m not sure where should I go next. Hope somebody can guide me

Here is a link to view the assignment of attributes in ActiveRecord code
base:

Well, I did a before_validation callback

def bv_callback
puts self.to_yaml
end

and I can see that the object has profesion_name (and every other)
attribute setted

but here

def profesion_related=(id)
puts self.to_yaml
end

there are only 3 attributes filled. I’m still not getting how does AR
manages to fill each attribute of the object after being saved

Simple. First, all setter methods are called on AR, and I’m guessing
profesion_related= was called the fourth, so only three attributes are
filled. After all setter methods are called (which means all attributes
are populated) the callbacks start, the first being the
before_validation one, which shows you the entire AR object.


Dheeraj K.

You should be able to retrieve the value in the callback. If it isn’t,
you’re doing something wrong. Make sure you remove your setters. Use
just the callback. If it doesn’t work, gist your code.


Dheeraj K.

On Fri, Jan 4, 2013 at 4:19 PM, Dheeraj K.
[email protected]wrote:

Simple. First, all setter methods are called on AR, and I’m guessing
profesion_related= was called the fourth, so only three attributes are
filled. After all setter methods are called (which means all attributes are
populated) the callbacks start, the first being the before_validation one,
which shows you the entire AR object.

If that’s the case… I’m not sure how to proceed then :frowning:
I thought active record would set object attributes first, and then
virtual
attributes or attr_writer methods
I’m doing this writer method because of this

def profesion_related=(value)
if value.to_i.to_s == value
#some code here if value is a number
else
#create a new profesion if is an string
end
#there’s a select input that changes the type of the
profesion_related
input in my form (between a select input and a text input
end

As far as I tried I can’t retrieve profesion_related value in my
before_validation callback cause its a virtual attribute