Array syntax in JSON in rails 3 on Heroku - ruby-on-rails

I have the following controller code:
def index
#profiles = Profile.where("(first_name || ' ' || last_name) ILIKE ?", "%#{params[:q]}%")
#autolist = []
#profiles.each do |profile|
user = User.find_by_id(profile.user_id)
#autolist.concat([{"id",profile.id,"name",profile.first_name+" "+profile.last_name,"email",user.email}])
end
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #autolist }
end
end
It works in my local environment, but crashes my app. Specifically this line: #autolist.concat([{"id",profile.id,"name",profile.first_name+" "+profile.last_name,"email",user.email}])
Any ideas?
I have a feeling it has to do with my local env using ruby 1.8.7 and the heroku app running 1.9.2

This works in 1.8.7:
>> h = {"id", 6}
=> {"id"=>6}
but not in 1.9.2:
>> h = {"id",6}
SyntaxError: (irb):4: syntax error, unexpected ',', expecting tASSOC
h = {"id",6}
^
from /Users/mu/Developer/.rvm/rubies/ruby-1.9.2-p180/bin/irb:16:in `<main>'
The rocket notation will serve you better:
#autolist.concat([{ "id" => profile.id, "name" => profile.first_name + " " + profile.last_name, "email" => user.email}])
I can't find any mention of this change in the 1.9.1 or 1.9.2 release notes and this is actually the first time I've seen the {'a', b} syntax for a Ruby Hash. Perhaps that notation was a deprecated feature that finally went away.
BTW, developing on 1.8.7 and deploying on 1.9.2 isn't the best idea.

Related

Wice_Grid CSV export not working - Uninitialized constant CSV::Writer

I "inherited" a rails aplication running with ruby 1.8.7 in development.
I have a wice_grid table which I'm trying to export in CSV and in development all goes perfect.
When I push it to production, i get the following error:
uninitialized constant CSV::Writer
The production machine is running Ruby 1.9.1 and from what I read, I suppose the problem comes from there.
I've tried to put:
required 'csv'
In the controller or the model, but nothing happens, development works, production does not.
Here is the controller code:
def index
require 'csv'
#service_requests = initialize_grid(ServiceRequest,
:name => "solicitudes",
:order => "created_at" ,
:order_direction => 'desc',
:include => [:user, :service],
:enable_export_to_csv => true,
:csv_file_name => 'Listado de Solicitudes'
)
export_grid_if_requested('solicitudes' => 'service_requests') do
#Si se pulsa en exportar se exportan todos las celdas de la tabla seleccionada (con filtros aplicados)
end
end
Here is the part of the view, which calls a partial:
<%= render :partial => 'service_requests' %>
Here is the partial, cropped for making the question not too long:
<%= grid(#service_requests, :show_filters => :always) do |service_request|
[...]
service_request.column :column_name => 'Nombre' , :attribute_name => 'name', :model_class => User do |sr|
sr.user.name
end
service_request.column :column_name => 'Apellidos' , :attribute_name => 'lastName' , :model_class => User do |sr|
sr.user.lastName
end
[...]
end %>
I read this thread but didnt help me much: write csv in ruby 1.9 and CSV::Writer
Thank you all in advance!
Somewhere, that you haven't posted, you are referencing CSV::Writer. This works locally because you're using Ruby 1.8.7, but your production server is using Ruby 1.9.1. CSV::Writer was deprecated with Ruby 1.9.
From the the docs:
# * The old CSV's Reader and Writer classes have been dropped.
Step one is to upgrade your local Ruby to the same version as the server. This will give you the same error locally, which should go away once you find and remove that CSV::Writer.
The CSV docs give examples of how to use the current CSV class to accomplish what CSV::Writer used to do. Here's an example:
# == Writing
#
# === To a File
#
# CSV.open("path/to/file.csv", "wb") do |csv|
# csv << ["row", "of", "CSV", "data"]
# csv << ["another", "row"]
# # ...
# end
Upgrading Ruby will probably raise other errors. But Ruby 1.8.7 was retired in 2013 so these are problems you're going to want to fix now rather than later.
Good luck!

Ruby default values error

I was reading the source code of a gem "activerecord-postgres-earthdistance".
While running the migration script, it threw an error on the following method
def order_by_distance lat, lng, order: "ASC"
It gave an error for order: "ASC"
syntax error, unexpected tLABEL
Isn't this valid Ruby syntax?
Ruby 2.0 supports keywords arguments
[5] pry(main)> def bar(a: "name", b: "fem"); puts a,b end
[6] pry(main)> bar(a: "John", b: "Male")
John
Male
[7] pry(main)> bar("John", "Male")
ArgumentError: wrong number of arguments (2 for 0)
from (pry):5:in `bar'
However the above is not valid in 1.9 see below:
ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-darwin12.4.0]
[2] pry(main)> def bar(a: "name", b: "fem"); puts a,b end
SyntaxError: unexpected ',', expecting $end
def bar(a: "name", b: "fem"); puts a,b end
^
[2] pry(main)> def bar(a: "name"); puts a end
SyntaxError: unexpected ')', expecting $end
def bar(a: "name"); puts a end
^
For better understanding you can read here and here
def order_by_distance(lat, lng, hash={})
puts hash[:order]
end
=> order_by_distance(lat, lng, order: "ASC")
=> "ASC"
use hash arguments in ruby

Rails: Cannot Parse JSON object neither with hash key or index

Weird question tag but still wanted to ask because even though it looks easy no matter what I've tried I could not accomplish
I'm trying to parse duration between to points from a URL given by Google Maps directions API. Thanks an answer I've received from here I was able to capture the JSON object and get to the duration object however no matter what I did I could not get the inner values "text" or "value" from the "duration" attribute.
Here is the response;
{
"text" : "6 mins",
"value" : 373
}
And here is the code I've written in rails
#request = Net::HTTP.get(URI.parse('http://maps.googleapis.com/maps/api/directions/json?origin=40.983204,29.0216549&destination=40.99160908659266,29.02334690093994&sensor=false'))
hash = JSON.parse #request
duration = hash['routes'][0]['legs'][0]['duration']
respond_to do |format|
format.html {render :index}
format.json {render json: duration}
end
Note: Of course, the [0] and ['text'] methods have been tried.
As a first thing you need to define duration as an instance variable to have it available in your views (if this is where you need to use it)
#duration = hash['routes'][0]['legs'][0]['duration']
duration["text"] and duration["value"] didn't work?
1.9.3p194 :001 > require 'net/http'
=> true
1.9.3p194 :002 > require 'json'
=> true
1.9.3p194 :003 > #request = Net::HTTP.get(URI.parse('http://maps.googleapis.com/maps/api/directions/json?origin=40.983204,29.0216549&destination=40.99160908659266,29.02334690093994&sensor=false'));
1.9.3p194 :004 > hash = JSON.parse #request;
1.9.3p194 :005 > duration = hash['routes'][0]['legs'][0]['duration']
=> {"text"=>"6 mins", "value"=>373}
1.9.3p194 :006 > duration["text"]
=> "6 mins"
1.9.3p194 :007 > duration["value"]
=> 373

Rails / Ruby not following Rublar on regular expression

I have the following expression that I have tested in Rubular and that successfully matches against a snippet of HTML:
Official Website<\/h3>\s*<p><a href="([^"]*)"
However, when I run the expression in Ruby, using the following code, it returns no matches. I've reduced it down to "Official\s*Website" and it matches that, but nothing further.
Are there any additional options I need to set, or anything else that I need to do to configure Ruby/Rails to start tracking Rubular?
matches = sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
if matches.nil?
puts "no matches"
else
puts "matches"
end
This is the relevant part of the snippet I'm matching against:
<h3>Official Website</h3><p>website.com</p>
your regular expression is correct. rubular should be working the same way your code does.
i tested it against ruby 1.8.7 and 1.9.3
irb(main):006:0> sidebar = ' <h3>Official Website</h3><p>website.com</p>'
=> " <h3>Official Website</h3><p>website.com</p>"
irb(main):007:0> sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
=> #<MatchData "Official Website</h3><p><a href=\"http://website.com\"" 1:"http://website.com">
-
1.9.3p0 :005 > sidebar = ' <h3>Official Website</h3><p>website.com</p>'
=> " <h3>Official Website</h3><p>website.com</p>"
1.9.3p0 :006 > sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
=> #<MatchData "Official Website</h3><p><a href=\"http://website.com\"" 1:"http://website.com">
if you want to quickly check why stuff is not working, you should try it in IRB or in your rails console. most of the times it's typo or bad encoding.

How to make Rails add line numbers / time stamps to log messages?

I use tail -f to display the log file when developing my Rails app.
It shows the log messages (in color! :), which is great.
But with so much information in the 80-width console, it becomes difficult to track where a certain "set" of log messages started when, say, I clicked on a button to GET a resource.
It would be easier if there was a line number or even a time stamp at the start of each log message/line. This way I could remember that I need to start looking at the log "after line number 2365" or "after 2010/10/10 23:33:23:45".
Is this possible to do? Is there some Rails internal option for this ?
why don't you just edit your desired environment's log tags
development.rb
config.log_tags [ lambda {|r| DateTime.now } ]
If you wanted to get a time stamp:
class ApplicationController < ActionController::Base
# ...
before_filter :log_tracker
def log_tracker
Rails.logger.add(1, "Log Date: #{DateTime.now}")
end
end
And format the date however you see fit....
That would work for Rails 2.1 +, prior you could access the ActiveSupport::Buffered log object with the constant: RAILS_DEFAULT_LOGGER
Get access to the actual log file with Rails.logger.instance_values["log"]
Getting the number of lines is difficult because the logger only opens the file for writing, probably for economy. I get an IOError: not opened for reading when I try.
`
Thanks #scaney.
I found a solution here.
I modified that code to add my own coloring highlights (for development only of course!) and now I can see things like 'parameters' in yellow in the console and I'm very pleased now!
In case someone is interested, here is the code I put at the end of environment.rb.
Here is my current (dirty) implementation. Will probably fix this up later (maybe make a gem, but for now this serves me fine)
WARNING
DIRTY CODE FOLLOWS! Use at your own risk!
module ActiveSupport
class BufferedLogger
#define the ANSI escape codes for normal and bright colors
$my_my_ansi_colors = {
:normal => "\x1B[0m",
:black => "\x1B[30m",
:red => "\x1B[31m", #red
:green => "\x1B[32m",
:yellow => "\x1B[33m",
:blue => "\x1B[34m",
:magenta => "\x1B[35m",
:cyan => "\x1B[36m",
:white => "\x1B[37m",
:bred => "\x1B[1m\x1B[31m", #bright red
:bgreen => "\x1B[1m\x1B[32m",
:byellow => "\x1B[1m\x1B[33m",
:bblue => "\x1B[1m\x1B[34m",
:bmagenta => "\x1B[1m\x1B[35m",
:bcyan => "\x1B[1m\x1B[36m",
:bwhite => "\x1B[1m\x1B[37m",
}
#take a string and using the keys in the hash, replace the keys in the
#string but surround the keys with ANSI color codes
#No idea how to retain the case of the key!(TODO someday)
def my_highlight msgx,hash
return msgx if msgx.blank?
return msgx if hash.empty?
hash.each_pair do |k,v|
if not k.nil?
msgx.gsub! Regexp.new(k, Regexp::IGNORECASE), $my_my_ansi_colors[:normal]+$my_my_ansi_colors[v]+k.upcase+$my_my_ansi_colors[:normal]
end
end
msgx
end
def add(severity, message = nil, progname = nil, &block)
return if #level > severity
message = (message || (block && block.call) || progname).to_s
#INSERT BEGINS
if not $myownglobalnumbercounter.nil?
$myownglobalnumbercounter += 1
else
$myownglobalnumbercounter = 1
end
level = {
0 => "DEBUG",
1 => "INFO",
2 => "WARN",
3 => "ERROR",
4 => "FATAL"
}[severity] || "U"
message = "\x1B[0m[%d %s] : %s" % [$myownglobalnumbercounter,level,message]
message = my_highlight message, {
"debug" => :white,
"error" => :bred,
"info" => :bwhite,
"warning" => :byellow,
"warn" => :byellow ,
"parameters" => :byellow,
"#" => :bgreen,
"ms " => :bmagenta,
"GET " => :bmagenta,
"PUT " => :bmagenta,
"POST " => :bmagenta,
"DELETE " => :bmagenta
}
#INSERT ENDS
message = "#{message}\n" unless message[-1] == ?\n
buffer << message
auto_flush
message
end
end
end

Resources