undefined method `safe_concat' for []:Array in rails 3 - ajax

I am trying to execute a flash partial like the following:
<% flash.each do |key, value| %>
<div class="flash <%= "#{key}" %>"><%= "#{value}" %></div>
<% end %>
And am getting the following error:
undefined method `safe_concat' for []:Array
The partial is being updated via an ajax request as follows:
page.replace_html "flash_messages", :partial => 'layouts/flash', :locals => { :flash => flash }
Any ideas? I have never seen something like this before.
Thanks.

Shouldn't it be the following?
<% flash.each do |key, value| %>
<div class="flash #{key}"><%= value %></div>
<% end %>
There's no need to wrap the key and value into "#{}". I suppose the nested <> is what made it choke on your line.
I can't try so I wouldn't know if it actually can access key outside of <% %>, so maybe you would need something like:
<% flash.each do |key, value| %>
<% class_names = "flash #{key}" %>
<div class="<%= class_names %>"><%= value %></div>
<% end %>

Related

iterate through array of hashes and output key, value

I'd like to do the following:
<% tags=[{"2":"birds"},{"3":"cars"}] %>
<% tags.each do |key, value| %>
<%=key %> <%=value %>
<% end %>
but this doesn't work. How would I do this (if possible)?
Since each hash can have any number of key/value pairs:
<% tags=[{"2":"birds"},{"3":"cars"}] %>
<% tags.each do |t| %>
<% t.each do |key,value| %>
<%=key %> <%=value %>
<% end %>
<% end %>

Why isn't this simple elsif working in Rails/Ruby?

If there is a flash notice > "Flash notice"
If there isn't a flash notice and you're on the homepage > "Welcome"
Code:
<% if flash %>
<% flash.each do |name, msg| %>
<%= content_tag :span, msg, id: "flash_#{name}" %>
<% end %>
<% elsif current_page('/') %>
<% print 'Hi' %>
<% end %>
It prints the flashes correctly but not the welcome on the home page. Doesn't seem to matter if I try current_page or root_url or print 'Welcome' or just plain "Welcome" with no code wrapper. Why?
Yes, almost, I wasn't checking the flash properly at the beginning of the block. This works now:
<% if flash.present? %>
<% flash.each do |name, msg| %>
<%= content_tag :span, msg, id: "flash_#{name}" %>
<% end %>
<% elsif current_page?('/') %>
Welcome to The Spain Report.
<% end %>
Thank you all!

How to save many items on one form rails?

I need to save many items to Cart on form, user enter quantity one form, and selected items goes to db, but now save only first entered quantity of item. Why?
my form
<%= form_for #cart_item do |f| %>
<% #category.items.each do |item| %>
<%= item.name %>
<%= f.hidden_field :item_id, :value => item.id %>
<%= f.text_field :qty %>
<% end %>
<%= f.submit %>
<% end %>
And controller
cart_items_controller.rb
class CartItemsController < ApplicationController
before_action :set_cart, only: [:create]
def create
#cart_items = CartItem.create(cart_items_params)
#cart_items.cart_id = #cart.id
if #cart_items.save
redirect_to :back
else
render root_path
end
end
private
def cart_items_params
params.require(:cart_item).permit(:id, :qty, :item_id, :cart_id)
end
def set_cart
#cart = Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
#cart = Cart.create
session[:cart_id] = #cart.id
end
end
There are a few problems here. I'll give you a little bump:
<% #category.items.each do |item| %>
<%= item.name %>
<%= f.hidden_field :item_id, :value => item.id %>
<%= f.text_field :qty %>
<% end %>
For each CartItem, this is going to create an input like this
<input name="qty">
This is problematic because only one (the last one in the DOM) will be submitted. You need to research fields_for and incorporate that into your loop in order to get unique names for each Item in the form.
This same issue follows through into your controller
def cart_items_params
params.require(:cart_item).permit(:id, :qty, :item_id, :cart_id)
end
This is going to look for a single :id, :qty, :item_id, and :cart_id, when in reality you're looking to accept multiple :item_id and :qty fields. You need to research Strong Parameters with nested has_many associations.
Finally you have this
#cart_items = CartItem.create(cart_items_params)
which is going to attempt to create a single CartItem when you're really trying to create multiple items and associate them back to the Cart. You need to research accepts_nested_attributes_for as well as more generally "rails form save has_many association". It's a widely covered topic here on SO and elsewhere.
I do this:
def create
#cart_items = params[:cart_items]
#cart_items.each do |c|
#cart_item = CartItem.new(c)
if #cart_item.qty.present?
#cart_item.cart_id = #cart.id
#cart_item.save
end
end
and form
<%= form_tag cart_items_path do %>
<% #cart_items.each do |cart_item| %>
<%= fields_for "cart_items[]", cart_item do |f| %>
<% #category.items.each do |item| %>
<%= item.name %>
<%= f.hidden_field :item_id, value: item.id %>
<%= f.text_field :qty %>
<% end %>
<%= f.submit %>
<% end %>
<% end %>
<% end %>

What happened to the flash messages in Rails 3.2.1?

I use this code to display flash messages in Rails 3.2.1 apps (well, I did):
<% flash.each do |name, msg| %>
<div class="alert alert-<%= name == :notice ? "success" : "error" %>">
<%= msg %>
</div>
<% end %>
But I get nothing. So I put <%= debug flash %> to see what I was getting back after an update and I get this:
--- !ruby/object:ActionDispatch::Flash::FlashHash
used: !ruby/object:Set
hash: {}
closed: false
flashes: {}
now:
How to I do the same thing?
The code I use for displaying flash messages and alerts is:
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, :class => "flash flash_#{name}" %>
<% end %>
But if your flash hash is empty, it's not going to display anything. Are you sure you're setting your flash hash properly?

What is the correct way to pass multiple arguments to a ruby == operator?

I'm a noob trying to do this:
<% if #page[:title] == "Portraits" %>
<%= render :partial => "/shared/slideshow" %>
<% elsif #page[:title] == "Escapes" %>
<%= render :partial => "/shared/slideshow" %>
<% elsif #page[:title] == "Articulos pa Web" %>
<%= render :partial => "/shared/slideshow" %>
<% end %>
There has to be a concise way to do this, but I just can't figure it out.
Avoid putting the logic you currently have, in a view.
Put this in a helper method instead and use it in the view:
def get_partial_to_render
if ["Portraits","Escapes","Articulos pa Web"].include? #page[:title]
"shared/slideshow"
else
"some_other_template"
end
end
#Note that the partial should not have a leading `/` in the path to it.
And in your view:
<%= render :partial => get_partial_to_render %>
Or, if you do not want to render a partial if a name is not in the array:
def render_my_partial?
["Portraits","Escapes","Articulos pa Web"].include? #page[:title]
end
<%= render :partial => "shared/slideshow" if render_my_partial? %>
Note that the ? is part of the method name. Isn't Ruby wonderful? :D
<% if ["Portraits", "Escapes", "Articulos pa Web"].include?(#page[:title]) %>
<%= render :partial => "/shared/slideshow" %>
<% end %>

Resources