alexhartley
alexhartley

Reputation: 65

Trying to push results of hash to an array - Ruby on rails

I'm just beginning to (hopefully!) learn programming / ruby on rails and trying to push the results of a hash to an array using:

ApplicationController:

def css_class
  css = Array.new
  product =  {@product.oil => ' oil', @product.pressure_meters => ' pressure_meters', @product.commercial => 'commercial'}
  product.each do |key, value| 
    if key == true
       css.push(value)
    end
  end
  сss.join
end

And this in the ProductsController:

def create
  @product = Product.new(params[:product])
  @product.css_class = css_class

  respond_to do |format|
    if @product.save
      format.html { redirect_to @product, notice: 'Product was successfully created.' }
      format.json { render json: @product, status: :created, location: @product }
    else
      format.html { render action: "new" }
      format.json { render json: @product.errors, status: :unprocessable_entity }
    end
  end
end

This only seems to only save the last thing that was pushed to the array, I tried the below code on it's own and it seems to work, so I'm baffled as to where I'm going wrong?

def css_class
  css = Array.new
  product =  {1 => ' pressure_meters', 2 => ' oil'}
  product.each do |key, value| 
    if key > 0
      css.push(value)
     end
  end
  css.join
end

puts css_class

Thanks in advance.

Upvotes: 0

Views: 2855

Answers (3)

alexhartley
alexhartley

Reputation: 65

Thanks for pointing me in the right direction. I kept getting a 500 internal server error with your code Bohdan, not sure why, but played around with it and eventually found this to work:

def css_class
css = Array.new
   product = { ' oil' => @product.oil, 
            ' pressure_meters' => @product.pressure_meters, 
            ' commercial' => @product.commercial }
   product.each do |key, value| 
  css << key  if value 
end

  css.join
end

Upvotes: 0

Bohdan
Bohdan

Reputation: 8408

In Ruby Hash can't have duplicate keys so

def css_class
  css = Array.new
  product = { @product.oil => ' oil', 
              @product.pressure_meters => ' pressure_meters', 
              @product.commercial => 'commercial' }
  product.each do |key, value| 
    if key == true
      css.push(value)
    end
  end
  сss.join
end

will not work because

irb(main):0> h = { true => 'foo', true => 'bar', false=>'foo', false => 'bar' }
=> {true=>"bar", false=>"bar"}

your second example works only because you have distinct keys (1,2) so let's refactor your code a bit

def css_class
  css = ""
  product = { ' oil' => @product.oil, 
              ' pressure_meters' => @product.pressure_meters, 
              ' commercial' => @product.commercial }
  product.each do |key, value| 
    css << key  if value
  end

  сss.strip
end

it can be simplified even more however previous version should work fine too

def css_class
  [ "oil ", "pressure_meters ", "commercial " ].inject(""){ |sum, val| sum += val if @product.send( val.strip ) }.strip
end

Upvotes: 2

rdvdijk
rdvdijk

Reputation: 4398

You can use Hash#values to get an array of your hash's values.

So:

product_values = product.values

And conditionally, you could pick the ones you want using select, like this:

product_values = product.select {|k,v| k == true }.values

Which is verbose for:

product_values = product.select {|k,v| k }.values

Upvotes: 1

Related Questions