Rails json response. Int converting to date - ruby-on-rails

I have a problem, with responding data in json.
Here is a code:
#data [
actions_by_type.each do |action|
[ action[:date].to_i, action[:activity] ]
end
]
respond_to do |format|
format.json { render :json => #data }
end
But responde is:
...{"date":"2013-04-29T20:20:00Z","activity":"87"}...
Why rails convert my int time, to string datetime?

You should use .map instead of .each.
#data = actions_by_type.map do |action|
[ action[:date].to_i, action[:activity] ]
end
respond_to do |format|
format.json { render :json => #data }
end
With .each the result of #data will be the actions_by_type instead of the new array.

x.each returns x so this:
x = actions_by_type.each do |action|
[ action[:date].to_i, action[:activity] ]
end
is equivalent to:
x = actions_by_type
You want to use map instead of each:
#data = actions_by_type.map do |action|
[ action[:date].to_i, action[:activity] ]
end

Related

Show won't render correct json

I am attempting to include some extra bits in my JSON using the below in my vehicles_controller:
# GET /vehicles/1
# GET /vehicles/1.json
def show
#vehicle = Vehicle.find(params[:id])
respond_to do |format|
format.json { #vehicle.to_json(:methods => [:product_applications_with_notes], :include => [:product_applications]) }
end
end
The vehicle model has both the method :product_applications_with_notes and the relationship has_many: :product_applications. However, when I run a request to http://localhost:3000/vehicles/1 the JSON output is as below:
{
"id": 1,
"make": "Acura",
"model": "ALL",
"year": 2001,
"body_style": "Car",
"created_at": "2014-10-22T20:06:00.157Z",
"updated_at": "2014-10-22T20:07:09.827Z"
}
It does not show the included extra bits. Why?
try to override the as_json method in Vehicle model.
something like:
def as_json(options=nil)
json_hash = super(options)
json_hash[:product_applications] = product_applications
json_hash
end

How to get the whole array of name in one array object using json?

In my code,i am parsing a JSON object like
[{"name":"karthi"},{"name":"shreshtt"},{"name":"jitu"},{"name":null},{"name":null},{"name":null},{"name":null}]
In this, I want to collect all names in an single array object. This is how my controller looks as of now. I want to store the resultant name array in #hotels variable.
controller.erb
respond_to :json, :xml
def index
#hotels = Hotel.all
respond_to do |format|
format.html # show.html.erb
format.json { render json: #hotels.to_json(:only => [ :name ]) }
end
end
view/hoels/index.json.erb
[
hotel: <% #hotels.each do |hotel| %>
{ 'name': "<%= hotel.name.to_json.html_safe %>" }
<% unless index== #hotels.count - 1%>
<% end %>
<% end %>
]
You want to add just the names to an array?
How about:
a = [{name: "karthi"},{name: "shreshtt"},{name: "jitu"},{name: nil},{name: nil},{name: nil},{name: nil}]
#hotel = []
a.collect{|a_name| #hotel << a_name[:name]}
=> ["karthi", "shreshtt", "jitu", nil, nil, nil, nil]
#hotel.compact!
=> ["karthi", "shreshtt", "jitu"]
What´s about that?
a = {}
a["hotel"] = []
array = [{"name"=>"kathi"}, {"name"=>"kathi2"}, {"name"=>"kathi3"}, {"name"=>"kathi4"}, {"name" => nil}]
a["hotel"] = array
a["hotel"].each do |v|
if v["name"] == nil
a["hotel"].delete(v)
end
end
a => {"hotel"=>[{:name=>"kathi"}, {:name=>"kathi2"}, {:name=>"kathi3"}, {:name=>"kathi4"}]}
You can do like following
hotels = Hotel.select("name").where("name is not NULL")
json_obj = {hotels: hotels}.to_json
format.json { render json: json_obj }

Remove blank element from array

When I'm saving multiple select from a ruby on rails form it appears to be adding a blank element at the front. How do I remove it? The field is selected_player.
{"utf8"=>"✓",
"authenticity_token"=>"H8W7qPBezubyeU0adnTGZ4oJqYErin1QNz5oK0QV6WY=",
"schedule"=>{"event"=>"1",
"result_id"=>"",
"time"=>"26/10/2012",
"duration"=>"15",
"arrival_time"=>"14",
"location_id"=>"25",
"selected_players"=>["", "38", "41"],
"team_id"=>"1",
"opponent_id"=>"7",
"home_or_away"=>"Home"},
"commit"=>"Save Event"}
controller
def update
#schedule = Schedule.find(params[:id])
#user = User.find(current_user)
#players = User.where(:team_id => current_user[:team_id]).all
respond_to do |format|
if #schedule.update_attributes(params[:schedule])
Notifier.event_added(#user,#schedule).deliver
format.html { redirect_to(#schedule,
:notice => "#{event_display_c(#schedule.event)} vs #{#schedule.opponent.name} was successfully updated.") }
format.json { head :no_content }
else
format.html { render :action => "edit" }
format.json { render :json => #schedule.errors, :status => :unprocessable_entity }
end
end
end
This works for empty strings:
array.delete_if(&:empty?)
To filter out empty strings and nil values use:
array.delete_if(&:blank?)
Example:
>> a = ["A", "B", "", nil]
=> ["A", "B", "", nil]
>> a.delete_if(&:blank?)
=> ["A", "B"]
Ref reject! of Array class
params["schedule"]["selected_players"] = ["", "38", "41"]
params["schedule"]["selected_players"].reject!{|a| a==""} #gives params["selected_players"] = ["38", "41"]
This should work as well.
params["schedule"]["selected_players"].reject!(&:blank?)
Something like:
params["selected_players"].select!{|val| !val.empty?}
should work
What is "selected_players"? Is it something like "collection_singular_ids" of the collection associations? If so, you can leave it as it is, because ActiveRecord will remove the blank elements from the array with following code:
ids = Array.wrap(ids).reject { |id| id.blank? }
If you want to handle this in the model rather than the controller you can add a setter method like this
def selected_players=(param_array)
write_attribute(:selected_players, param_array.reject(&:blank?))
end
I think params["selected_players"].compact is the most succinct.
Docs are here: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-compact

Rails easyist way to create hash with certain attributes and also nested

In my controller I have:
def search
#sog = Konkurrencer.where("titel like ?", "%#{params[:q]}%")
#kate = []
#sog.each do |kat|
h = {}
kat.attributes.each{|k,v| h[k] = v.respond_to?(:force_encoding) ? v.dup.force_encoding("UTF-8") : v }
#kate << h
end
respond_to do |format|
format.html
format.json { render :json => #kate }
end
The problem is that the JSON contains all the attributes for the model. How do I create a JSON that have only ID, url and titel?
The JSON should also contain the key "url" which key should be the URL for the associated photo. I use paperclip. The path is: #konkurrencer.photo.image.url
UPDATE:
My search.json.erb:
[
<% #sog.each do |kon| %>
{"id":"<%= kon.id %>","titel":"<%= kon.titel %>"},
<% end %>
]
How do I remove the , for the last loop?
Create an array with the list of attributes you want to display. Use select query method to get only this fields in the SQL request. And finally loop on this attributes to fill the JSON array:
def search
displayed_attributes = %w{id url titel}
#sog = Konkurrencer.select(displayed_attributes.join(',')).where("titel like ?", "%#{params[:q]}%")
#kate = []
#sog.each do |kat|
h = {}
displayed_attributes.each do |attribute|
v = kat[attribute]
h[attribute] = v.respond_to?(:force_encoding) ? v.dup.force_encoding("UTF-8") : v
end
#kate << h
end
respond_to do |format|
format.html
format.json { render :json => #kate }
end
end

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.
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
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
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

Resources