Undefined method `goals_against' for #<YAML::Object:0x5584864>

Hi all,

I have a serialized object (of class Goals) in my statistics table. I
store it in the value row of statitics
When I do:
goals = Statistic.find(1).value.goals_against I get
undefined method `goals_against’ for #YAML::Object:0x5584864
(goals_against is a member of Goals)

Someone knows why this happens?

Thanks
Stijn

Would you share your model definitions and the code that you use to
create/save the statistic and goals instances?

Craig

Thanks for the reply,
Please find the models, database and class definition below.

I try to get the goals object like this
@statistics = @event.statistics.find(:all, :include
=> :statistic_definition)
goals_a = @statistics.first.value.goals_against
=> undefined method `goals_against’ for #YAML::Object:0x579cbec

The YAMLvalue in the database is:
— !ruby/object:Goals
goals:
1: 2
goals_against: 2
goals_for: 2
version: 1

The model:
class Statistic < ActiveRecord::Base
belongs_to :event
belongs_to :statistic_definition
serialize :value
end

statitics table
id int(11)
value text
event_id int(11)
statistic_definition_id int(11)

The object I serialize
class Goals
attr_accessor :goals
attr_accessor :goals_for
attr_accessor :goals_against
attr_accessor :penalty_for
attr_accessor :penalty_against

def initialize(goals, goals_against, penalty_for = nil,
penalty_against = nil)
@version = 1
@goals = goals
set_goals_for()
@goals_against = goals_against.to_i
unless penalty_for.nil?
@penalty_for = penalty_for.to_i
@penalty_against = penalty_against.to_i
end
end

private
def set_goals_for
@goals_for = 0
@goals.each_value {|value| @goals_for += value.to_i }
end
end

On Apr 17, 4:00 pm, “Craig D.” [email protected]

I tried something a bit simpler just to see if it would work. Here’s
what I
did.

  • create a new rails app (rails blah)
  • create the databases (rake db:create:all)
  • generate a Statistic model with a value column of type text
    (script/generate model statistic value:text)
  • run migrations (rake db:migrate)
  • create a non-ActiveRecord class named Goals with one attributed named
    goals_against
  • run the Rails console (script/console) and do the following:

Statistic.create! :value => Goals.new(3)
=> #<Statistic id: 2, value: #<Goals:0x1928960 @goals_against=3>,
created_at: “2008-04-17 13:22:10”, updated_at: “2008-04-17 13:22:10”>

stat = Statistic.find :first
=> #<Statistic id: 2, value: #<Goals:0x1911ddc @goals_against=3>,
created_at: “2008-04-17 13:22:10”, updated_at: “2008-04-17 13:22:10”>

stat.value.goals_against
=> 3

I didn’t have any problems along the way. Other than using simpler
models/classes, nothing jumps out at me as to what you might have done
that’s causing your problem.

Here’s the source code.

class Statistic < ActiveRecord::Base
serialize :value
end

class Goals
attr_accessor :goals_against

def initialize(goals_against)
@goals_against = goals_against
end
end

Here’s the generated schema from db/schema.rb.

ActiveRecord::Schema.define(:version => 1) do

create_table “statistics”, :force => true do |t|
t.text “value”
t.datetime “created_at”
t.datetime “updated_at”
end

end

Let me know how it goes and if there’s anything more I can do.

Regards,
Craig

Many thanks for the help.

I have found some strange behavior:

I use understanding code to first insert a then read a Goals object
from the database
stat = Statistic.new
stat.event_id = 1
stat.statistic_definition_id = 1
stat.value = Goals.new({1 => 1, 2 => 2}, 1)
stat.save

@statistics = @event.statistics.find(:all, :include
=> :statistic_definition)
goals_a = @statistics.first.value.goals_against

When I use above code the deserialization works as it should.

The next time, when I only get the Goals object out of the database
(and not insert it first), deserialization fails. It seems that I have
to insert and read the object in the same request otherwise
deserialization fails.

This sounds very weird and I have no idea what causes this.

Regards,
Stijn

On Apr 17, 7:35 pm, “Craig D.” [email protected]

I found out something more. When I do:
Goals.new({1 => 1, 2 => 2}, 1)
@statistics = @event.statistics.find(:all, :include
=> :statistic_definition)
goals_a = @statistics.first.value.goals_against

it works.
@statistics = @event.statistics.find(:all, :include
=> :statistic_definition)
goals_a = @statistics.first.value.goals_against

I get undefined method `goals_against’ for #YAML::Object:0x539a954

Can it be that the deserializer doesn’t know the Goals object somehow
by default? I put the Goals class file in my Lib directory.

Regards,
Stijn

When I do

it also works. I thus just have to use the Goals class

In the example that I created, I put the Goals class in app/models even
though it’s not an ActiveRecord model. Does putting your Goals class in
app/models make a difference?

Regards,
Craig

Hi Craig,

Putting it in the apps/model solves the problem. I though tough you
should put all your classes in the lib dir.

regards,
Stijn

On Apr 19, 3:00 pm, “Craig D.” [email protected]

I’ve used the lib dir only once for a very simple rake task, but my
impression is that code in the lib dir should be available to the rest
of
the app. If I have a chance to do a little learning, I’ll report back.

Craig

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs