insecure-IT
insecure-IT

Reputation: 2188

Why am I getting `method_missing`?

I'm not sure but I think my something may not be right with my relations? I'm getting method_missing. Is it because I'm getting an Array back from active-record.?

event = Event.last
  Event Load (16.2ms)  SELECT "event".* FROM "event" ORDER BY "event"."sid" DESC, "event"."cid" DESC LIMIT 1
=> #<Event sid: 4, cid: 49, signature: 493, timestamp: "2014-06-25 20:22:57">

event.sensors
  Sensor Load (12.7ms)  SELECT "sensor".* FROM "sensor" WHERE "sensor"."sid" = 4
=> [#<Sensor sid: 4, hostname: "VS-101-Z1:dna2:dna3", interface: "dna2:dna3", filter: nil, detail: 1, encoding: 0, last_cid: 50>]

This is where it all goes to crap, I'm expecting VS-101-Z1:dna2:dna3 but instead I get method_missing:

event.sensors.hostname
  Sensor Load (22.4ms)  SELECT "sensor".* FROM "sensor" WHERE "sensor"."sid" = 4
NoMethodError: undefined method `hostname' for #<ActiveRecord::Relation:0x007fedd377c900>
from /Library/Ruby/Gems/2.0.0/gems/activerecord-3.2.14/lib/active_record/relation/delegation.rb:45:in `method_missing'

Event Table:

class Event < ActiveRecord::Base
  # DB Schema
  # sid | cid | signature | timestamp
  #----------------------------------

  attr_accessible :sid, :cid, :signature, :timestamp
  self.primary_keys = :sid, :cid
  self.table_name = 'event'
  has_many :sensors, :foreign_key => :sid
  has_many :signatures, :foreign_key => :signature
end

Sensor Table:

class Sensor < ActiveRecord::Base
  # DB Schema
  # sid | hostname | interface
  #---------------------------

  attr_accessible :sid, :hostname, :interface
  self.table_name = 'sensor'
  belongs_to :event, :foreign_key => :sid
end

Upvotes: 0

Views: 517

Answers (1)

Helios de Guerra
Helios de Guerra

Reputation: 3475

You cannot call an instance method on an array of objects, which is what you get when you call event.sensors.

If you expect a single return value, you'll have to select an instance of your array to call the instance method on, e.g. event.sensors.first.hostname

However, if you are looking to return an array of all the hostnames for event.sensors you'll probably want to use the pluck method described here:

http://guides.rubyonrails.org/active_record_querying.html#pluck

event.sensors.pluck(:hostname)

This is preferable to using map to iterate over the array since pluck uses a SQL query while map pulls back the entire collection of ActiveRecord objects into an array and then iterates over each instance.

Upvotes: 3

Related Questions