Mani
Mani

Reputation: 2563

Perform map method on model object Ruby on Rails

I queried @ingredient = Feed.find(params[:ingredient_id]) and it returned a model hash object like

< Feed id: 1, ingredient: "Sorghum, Grain", cost_kg: 26.0, d_m: 88.0, c_p: 11.0, m_e: 3212.0, c_f: 2.3, e_e: 2.1, ash: 2.6, ca: nil, p:
0.32, lys: 0.22, met: 0.15, trp: 0.17, created_at: "2016-01-26 12:54:05", updated_at: "2016-01-26 12:54:05">

I want to take divide all the float values, in the response with 2 . Please pardon me if it sounds creepy :P

I tried to do it through map/select combination but couldn't succeed

Upvotes: 1

Views: 4395

Answers (3)

Semjon
Semjon

Reputation: 1023

Try this way:

@ingredient.attributes.each do |key, value|
  if value.is_a? Float
    @ingredient[key] = value / 2
  end
end

This code iterates over attributes of @ingredient object and if an attribute is a Float, then divides it by 2 and reassign new attribute value back to @ingredient.

Upvotes: 3

Jaehyun Shin
Jaehyun Shin

Reputation: 1602

You can get float type by columns_hash method

call Feed.column_hash -> You can get all column infomation

Somthing like, (depend on your db adapter)

> Reservation.columns_hash['price_amount']
=> #<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007fd0ca931a78
 @array=false,
 @cast_type=
  #<ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float:0x007fd0b235d420
   @limit=nil,
   @precision=nil,
   @scale=nil>,
 @default=nil,
 @default_function=nil,
 @name="price_amount",
 @null=true,
 @sql_type="double precision">

you can get float type by sql_type or class name of cast_type
So, you can get float column

float_columns = Feed.columns_hash.select { |_k, v| v.cast_type.class.name.include? 'Float' }

and divide

feed = Feed.find(params[:ingredient_id])
float_columns.keys.each do |attr|
  feed[attr] = feed[attr] / 2 unless feed[attr].nil?
end

Upvotes: 3

equivalent8
equivalent8

Reputation: 14227

@ingredient =    Feed.find(params[:ingredient_id]) 

@ingredient
  .attributes
  .symbolize_keys
  .delete_if { |k| [:updated_at, :created_at, :id, :ingredient].include?(k) }
  .map{ |k, v| { k => v.to_f / 2 } }

this will return

[{:cost_kg=>13.0}, {:d_m=>44.0}, {:c_p=>5.5}, {:m_e=>1606.0}, {:c_f=>1.15}, {:e_e=>1.05}, {:ash=>1.3}, {:ca=>0.0}, {:p=>0.16}, {:lys=>0.11}, {:met=>0.075}, {:trp=>0.085}]

Upvotes: 1

Related Questions