cancue
cancue

Reputation: 414

How do I get several attributes value and method value from an ActiveRecord model?

To solve my problem, I set fictitious Car Model below:

Car Model has
3 attributes(id, car_name, owner_name) and
2 methods which return integers(riders, passengers).

I want to get ONE HASH which has the values of 2 attributes and 2 methods from all of cars. To solve this problem, my temporary solution is below:

json_format = Car.all.to_json(only: [:car_name, :owner_name], methods: [:riders, :passengers])
final_hash = ActiveSupport::JSON.decode(json_format)

This works, but this is bad because I use 'to_json' method only for its optional function.
Is their any other choice to getting the one hash directly from Car Model via its own optional function?

Upvotes: 0

Views: 77

Answers (3)

Max Williams
Max Williams

Reputation: 32933

I agree that turning it into Json and back is pretty stupid. I would do this like so.

Car.all.collect{|car| hash = {}; [:car_name, :owner_name, :riders, :passengers].each{|key| hash[key] = car.send(key)}; hash}

it would be cleaner to put this into a method in the object

#in Car class
def stats_hash
  hash = {}
  [:car_name, :owner_name, :riders, :passengers].each do |key|   
    hash[key] = self.send(key)
  end
  hash
end

then do

Car.all.collect(&:stats_hash)

Upvotes: 0

ConnorCMcKee
ConnorCMcKee

Reputation: 1645

I feel the same as you that using the json commands for a method unrelated to json is poor practice.

If you don't mind being verbose, you could do something like this:

formatted_cars = Array.new
Car.all.each do |c|
  formatted_cars.push( car_name: c.car_name,
                       owner_name: c.owner_name,
                       riders: c.riders,
                       passengers: c.passengers )
end

I find when hitting both attributes and methods it's cleanest just to specify the assignments like this. This is also the technique I would use in passing an object with its virtual attributes to javascript.

Upvotes: 0

Kristján
Kristján

Reputation: 18803

Use as_json. It's what to_json uses under the hood, and accepts all the same options but returns a Hash.

Upvotes: 3

Related Questions