postgres array and rails 4 erb - ruby-on-rails

i have a view in my postgres database that returns an array on my frequencies column. unfortunately, it sometimes returns values like {NULL} (due to the raw data).
in my rails view, i have something like:
dataset = [
<% #item.each do |i| %>
{
name: "<%= i.device %>"
lng: <%= i.longitude %>
lat: <%= i.latitude %>
frequencies: <%= i.frequencies.to_s.html_safe %>
},
<% end %>
]
which appears to work great - except when it reaches a record that contains {NULL}:
in the javascript console it shows:
Uncaught ReferenceError: nil is not defined
and in the html it shows:
...
}, {
name: "blah",
lng: -122.2,
lat: 37.4,
frequencies: [nil]
}, {
...
i could fix this by iterating through the list in the controller, but i think this would be rather long winded (and a waste of cycles).
is there a way i can get the erb to output the 'correct' [] in (instead of [nil]) json when it's null?

Try this:
<%= i.frequencies.compact %>
compact example:
[nil].compact #=> []
[1,2, nil, 3, nil].compact #=> [1,2,3]

Related

passing an array to a rails button_tag

the following
#ids.class
is being properly returned as Array
But when it is being used as values
<%= button_tag 'Top', value: #ids, type: :submit, name: :top %>
the params submitted are:
"top"=>"17515 30784 31614 32342 32362 31815 31813 32386 33004 32483 31750 32478 16331 11728"
which is a string.
> params[:top].class
String
Transforming via Array(params[:top]) only results in a single element
["17515 30784 31614 32342 32362 31815 31813 32386 33004 32483 31750 32478 16331 11728"]
Transforming via substitution of space with a comma, to then generate a proper array
params[:top].sub(" ", ",")
only handles the first space
"17515,30784 31614 32342 32362 31815 31813 32386 33004 32483 31750 32478 16331 11728"
Modifying the tag to value: #ids.to_s returns the same situation.
How can this be properly processed by the subsequent action as an array?
How can this be properly processed by the subsequent action as an array?
Unless you want to do some wonky parameter processing like params[:top].split(' ') you need to use multiple parameters in a form or query string to pass an array.
To pass array parameters in Rack (the CGI that Rails sits on top of) you need to pass multiple formdata pairs where the key ends with [].
foo[]=1&foo[]=2&foo[]=3
# resulting params hash
=> { "foo" => ["1", "2", "3"] }
This is actually processed the same way regardless if its passed in the query string or request body.
For query strings #to_query handles this automatically:
irb(main):004:0> CGI.unescape( { foo: [1,2,3]}.to_query )
=> "foo[]=1&foo[]=2&foo[]=3"
For forms you can just create hidden inputs:
<% values.each do |v| %>
<%= hidden_field_tag 'top[]', v %>
<% end %>
Max's answer is correct but will use n hidden form fields to generate the foo[]=1&foo[]=2&foo[]=3 response.
If you still want to use it with the button_tag input field you can do something like the following
# In your form file
<%= button_tag 'Top', value: #ids, type: :submit, name: :top %>
And then use it like that in your controller
# Use #split on the string params
params[:top].split
Example
"10 20 30".split => ["10", "20", "30"]
You can always pass a delimiter to split by on the #split method
#split documentation

Render h3 only if this type doesn't exist yet

I am quite new to ruby and working on a project. I have a database of items that shows different products, links, and svg files. I keep it in a collection and loop through the items. For now, I only want to render a type name if it doesn't exist.
`<%= render partial: "site/main, collection: [
{
type: 'Garden',
link: '/garden/pot',
svg: '//images/pot.svg',
name: 'Pot of your dreams',
description: 'A perfect pot for any household'
},
{
link: '/garden/flower',
svg: '//images/flower.svg',
name: 'A perfect flower',
description: 'You need to buy it for your garden!'
}
]`
I want to render the h3 only if it doesn't exist yet:
<h3><%=main[:type]%></h3>
So it is rendered only once, not all the time. There will be an h3 element rendering Garden only once.
The best approach will be to group your collection by type. And then render collection within the type as another collection.
Here is what I mean(feel free to change the names):
After you regroup by collection type you'll get something like this(it may have a different format, but you'll get the idea):
collection = [
{ type: 'Garden', type_collection: [
{
link: '/garden/pot',
svg: '//images/pot.svg',
name: 'Pot of your dreams',
description: 'A perfect pot for any household'
},
{
link: '/garden/flower',
svg: '//images/flower.svg',
name: 'A perfect flower',
description: 'You need to buy it for your garden!'
}
],
type: 'Type #2', type_collection: [
{
link: '/garden/flower2',
svg: '//images/flower.svg',
name: 'A perfect flower from type2',
description: 'You need to buy it for your garden!'
}
]
}]
then your site/main can have something like this:
<p>
<h3><%= main[:type] %></h3>
<%= render partial: 'site/type_collection', collection: main[:type_collection] %>
</p>
and your site/type_collection will have whatever you initially had:
<p>
<%= type_collection[:link] %>
</p>
In your partial which renders items of the collection, you can generate h3 using tag helper
<%= tag.h3 item[:type].presence || main[:type] %>
assuming each item is in the collection is represented by locals item

How to display value from this array in Ruby on Rails

I have been working on a side project and I'm kind of stuck here
So I extract some info in the form of an array using
<%= #link.pixels.select{|x| x['platform']=='Facebook'} %>
Where the result is
[#<Pixel id: 1, platform: "Facebook", name: "Facebook", pixel: "189874014884804", created_at: "2017-10-17 18:44:13", updated_at: "2017-10-17 18:44:13">]
How can I extract the value of pixel from this array?
Also, is this the correct approach to select? What if there are two duplicate entries in Pixel with the platform name "Facebook"?
I have been stuck at this for while now.
If what you are trying to do is display the value of the pixel attribute from a collection of Pixel instances where the platform matches the string "Facebook" this is what you'd do:
<% #links.pixels.each do |pixel| %>
<% if pixel.platform == 'Facebook' %>
Pixel: <%= pixel.pixel %>
<%end%>
<%end%>

Why scan method for strings prints out directly in rails and ingnore the rest of code

I have a field (string) in DB that stores a list of values gotten from checkbox if they are checked:
Example:
checkbox1 [X] //Value 1
checkbox2 [ ] //Value 2
checkbox3 [X] //Value 3
checkbox4 [X] //Value 4
checkbox5 [ ] //Value 5
It stores in database the string "--- -'1' -'3' -'4'" (w/o the double quotes) I don't know why because in my form I have:
<% SoProfile::LANGUAGES.each do |key, value| %>
<div class="fluid">
<%= f.label :languages,class: "checkbox" do %>
<%= key %> <%= f.check_box :languages, {:multiple => true}, value, nil %>
<% end %>
</div>
<% end %>
in the model (I don't want to use a DB table for this):
LANGUAGES = { Espanol: 1, Ingles: 2, Portugues: 3, Italiano: 4, Mandarin: 5 }
anyways, it stores that string "--- -'1' -'3' -'4'" for the example above, I want to show a country flag according to the language instead of putting the language name.
I've created a helper method for this:
def insert_languages(string)
string.scan(/\d/).each do |i|
case i
when i == "1"
content_tag(:div,"",class: 'flag flag-co')
end
end
end
that is called in my view:
<tr>
<td>Idiomas <br />
<%= insert_languages(#so_profile.languages) %>
</td>
</tr>
But the helper method won't pass from .scan and will print out the hash ["1" "3" "4"] directly, it is, it never reaches the case code, like if there were a return in the string.scan(.. line of code.
How can I prevent rails from returning the hash and instead print the flag?
Try changing your method to following:
def insert_languages(string)
result = ""
string.scan(/\d/).each do |i|
case i
when "1"
result += content_tag(:div,"",class: 'flag flag-co')
end
end
result
end
You're getting hash since ruby returns values from .each block. Ruby returns last value from function implicitly. About your storing method - I suggest you reconsider your storage method. In mongoid, for example, you can use arrays. For active record something like that could solve your problem.
The each iterator doesn't return more than one value. If no return is explicitly declared, it will return the last object accessed in the method, which in this case is string.scan(/\d/). You can change .each to .map, which will return an array of content_tags, which would would iterate over in the view:
<% insert_languages(#so_profile.languages).each do |lang| %>
<%= lang %>
<% end %>

show data from table on Ruby

I am new on Ruby and I am trying get data from table. so when read this
<%= puts #note.inspect %> I have this this result.
[#<Note id: 1, user_id: 1, note_type: 0, text: "Barev dzez", lat: 40.2290542420142, lng: 44.420879046875, deleted: false, created_at: "2012-04-26 14:10:05", updated_at: "2012-04-26 14:10:05">]
So when I call Note.text (for instance) I got nil result. So what should I write here to get data from array?
Thanks
#note is an Array with one Note object. You need to get the element first. For example:
<%= #note.first.text %>
You are retrive record in an array so you need to call like this
<%= puts #note.first.text %>
or
<%= puts #note.last.text %> if there is only one record
But you don't specify how you are retrive records..

Resources