Rails: Error in action "Timeout::Error in CarsController#show" - ruby-on-rails

When I load my action CarsController#show in browser, I get this error message:
Timeout::Error in CarsController#show
execution expired
And the error pointing out on this line:
country = GeoIp.geolocation(ip, :precision => :country)
The whole action:
def show
#car = Item.find_by_car_key(params[:car_key])
ip = request.remote_ip
geo_key = 'my geo key'
GeoIp.api_key = geo_key
country = GeoIp.geolocation(ip, :precision => :country)
puts country.inspect
respond_to do |format|
format.html # show.html.erb
format.json { render json: #item }
end
end
How can I avoid this error message and use it always when this action will be loaded?
Thank you

Assuming you are using the GeoIP gem found here
The error is related with the time out, maybe geoip gem is taking to much time to fetch the ip info, so after your Api Key set GeoIp timeout
According to the gem readme,
It is possible to set a timeout for all requests. By default it is one second, but you can easily set a different value. Just like you would set the api_key you can set the timeout:
Try
GeoIp.timeout = 5 # In order to set it to five seconds
Update
I will recommend you another gem, because geoip is nor uptodate, take a look at Geocoder
https://github.com/alexreisner/geocoder, it can take the ip address from the request automatically like
request.location.country
request.location.city

I would recommend using the geocoder gem in combination with maxmind or freegeoip
works well in my production app (freegeoip sometimes detects the wrong country, but its free)

Related

How to determine the cause of a delay before an action is hit in my Rails app?

I've come to a dead-end with my troubleshooting, and I'm really hoping someone can help.
I'm using rack-mini-profiler to help locate a potential memory leak in my Rails website. I narrowed it down to the method that is being called.
High-level profile: rack-mini-profiler high-level
SQL profile: rack-mini-profiler results
In the SQL profile picture, notice the start times of the query just above and just below the gray bar have a difference of 1037ms. That is the delay I am noticing, and it grows until I restart the application.
When running this locally, I can monitor the terminal. When that method is requested, there is just that 1 second delay, and then it executes. No queries or commands show up in the terminal during that delay.
Does anyone have any ideas as to how I can figure out what is causing this delay?
I'm using Ruby 2.2.0 with Rails 4.1.6.
Thanks!!
EDIT:
This is the method rack-mini-profiler is pointing to:
def submit_answer
quiz_attempt = CourseCompletion.find_by_id(params[:course_completion_id]).quiz_started
choice = Choice.new(:answer_id => params[:answer], :quiz_attempt_id => quiz_attempt.id)
#success = choice.save
#answer = choice.answer
#question = #answer.question
#quiz_attempt = choice.quiz_attempt
render :layout => false
end
take a look on ruby-prof github.com/ruby-prof/ruby-prof. Try to wrap body of your action into the block:
require 'ruby-prof'
# profile the code
RubyProf.start
# ... code to profile ...
result = RubyProf.stop
# print a flat profile to text
printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT)
and you should receive output in console which would look like:
You also can redirect output of profiler to log or some file on the server.
So in your case edit code:
def submit_answer
require 'ruby-prof'
# profile the code
RubyProf.start
quiz_attempt = CourseCompletion.find_by_id(params[:course_completion_id]).quiz_started
choice = Choice.new(:answer_id => params[:answer], :quiz_attempt_id => quiz_attempt.id)
#success = choice.save
#answer = choice.answer
#question = #answer.question
#quiz_attempt = choice.quiz_attempt
render :layout => false
result = RubyProf.stop
# print a flat profile to text
printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT)
end
Add to gemfile
gem 'ruby-prof'
Run bundle install and restart the server. Try to run action again and check rails console output. Methods on top of the table are most time consuming.

How to save data using Redmine issue model

I need to modify the issue's start_date and due_date some how,
But I haven't used Rails before, so I don't know how the it run in server,
And I need to implement it in a short time.
So I add these code in the controller,
def date
issue = Issue.find(params[:id])
issue.start_date = params[:start_date]
issue.due_date = params[:due_date]
ntc_str = "Fail to save!" + params[:id]
if issue.save
ntc_str = 'Issue saved!'
end
flash[:notice] = ntc_str;
redirect_to :controller => 'gantts', :action => 'show', :project_id => params[:p_id]
end
It runs when I access it by myself
It always failed and the "ntc_str" always is "Fail to save!" if I use javascript to access it.
For example:
It runs when I input the url "http://xxx.xxx.xxx.xxx/date?id=6&project_id=test&start_date=2016-06-08&due_date=2016-06-30" by hands,
But it failed when I use javascript "window.location.href='/date?id=6&project_id=test&start_date=2016-06-08&due_date=2016-06-30'"
It runs when I input the params in the form I create and click to submit it,
But it failed when I use javascript "document.getElementById('start_date').value = '2016-06-30'; /..../ $('#test-form').submit()"
Could you tell me why it always fails and how can I use the issue model? I have be crazy now.
It would be useful, if you provide some logs with each cases you try.
Also, you can see what goes wrong with issue, when you try to save it, with:
if issue.save
ntc_str = 'Issue saved!'
else
Rails.logger.error(issue.errors.full_messages)
end

How to avoid bug if geocoder sends me empty array when retrieving country of user (Rails 4/geocoder)

I am building a daily deal Rails app
I am displaying to the user only the deals of the country i associate him with thanks to geocoder gem.
I wonder what would happen if geocoder fails (for any reason) to retrieve the country and sends an empty array, as i think it does when it fails to send ip( see https://github.com/alexreisner/geocoder#error-handling)
class StaticPagesController < ApplicationController
def home
#deals = deal_in_user_country.featured_on_hp
respond_to do |format|
format.html # home.html.erb
end
end
# create a scope to filter the deals that meet the user's country
def deal_in_user_country
Deal.where(country: set_location_by_ip_lookup.country || 'United States') # if geocoder gets pb then default = US version
end
end
end
As you see, I tried to use || and puts 'United States' but I don't think it will work. i think that if geocoder sends empty array , set_location_by_ip_lookup=[] and then set_location_by_ip_lookup.country will generate an error, am I right ?
How should i avoid bugs when geocoder sends an empty array ?
For info if it helps, here is how I set country in concerns/CountrySetter
module CountrySetter
extend ActiveSupport::Concern
included do
before_filter :set_location_by_ip_lookup
end
def set_location_by_ip_lookup
if Rails.env.development? or Rails.env.test?
Geocoder.search(request.remote_ip).first
else #in production
request.location
end
end
end
Your code should be fine, if geocoder allways returns at least an empty array (except I would not name this mehtod set_ because it's not setting anything)
Try out on irb
{a: [:d].first || :b}
=> {:a=>:d}
{a: [].first || :b}
=> {:a=>:b}
However i would put this in paranethesis to make it clear
Deal.where(country: (set_location_by_ip_lookup.country || 'United States'))
Gecodoer.search shouldn't be throwing exceptions, otherwise it would be named Geocoder.search! according to an unwritten ruby convention. I would double check this by plugin out the internet connection and see what happens

POST method/Create action works for some methods but not others, Feedzirra

Ok I am making a JQuery .post request to a server to insert some data. It only works sometimes depending on what methods are in the Rails create method.
Here are the specifics. I have a Rails app with Backbone.js on the frontend. In my frontend code I make this .post request
$.post('/publications');
Seems simple enough. I have a Publication model as well as
resources :publications
in the router. Now in my Publications controller I augmented the create method to the following:
def create
feed = Feedzirra::Feed.fetch_and_parse(publication_params[:url])
params = {:name => feed.title}
#publication = Publication.new(params)
respond_to do |format|
if #publication.save
format.html { redirect_to #publication, notice: 'Publication was successfully created.' }
format.json { render action: 'show', status: :created, location: #publication }
else
format.html { render action: 'new' }
format.json { render json: #publication.errors, status: :unprocessable_entity }
end
end
end
Feedzirra is a gem that parses RSS feeds. When I make the POST request like this I get a 500 (Internal Server Error) and this message from my server logs
NoMethodError (undefined method `title' for {}:Hash):
app/controllers/publications_controller.rb:28:in `create'
Rendered /Users/ericabt1/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (40.3ms)
Rendered /Users/ericabt1/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.1ms)
Rendered /Users/ericabt1/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.0ms)
Rendered /Users/ericabt1/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (54.7ms)
What is confusing me is that if I choose a different method than 'title' like 'entries' or 'nil?' the POST request works just fine. I know that 'title' is indeed a method because when I go into Rails console and create a test Feedzirra object and look at the various methods available I see that 'title' is one of them.
Why does my POST request work for some of these method but not others?!?!?!?!
* UPDATE ****
After taking krabbi and Alexander Zolotko's advice I started playing with what FeedZirra is returning. It looks like the line
feed = Feedzirra::Feed.fetch_and_parse(publication_params[:url])
is returning an empty hash.
Now when I run the same line in the rails console and hardcode a url in there it returns the proper hash and I am able to grab the title and other values. So it looks like the issue lies with
publication_params[:url]
Still working on this and open to suggestions:)
* UPDATE PART TWO *
I thought the problem was that there was no url column in the Publication Model. So I made the proper migration. So here is the schema:
create_table "publications", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.string "url"
end
Back to the controller I have at the bottom:
private
# Use callbacks to share common setup or constraints between actions.
def set_publication
#publication = Publication.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def publication_params
params.permit(:name, :url)
end
publication_params[:url] is still returning nil. I have also tried the line:
params.require(:publication).permit(:url, :name)
which just gives me 400 Bad request error
As Alexander Zolotko points out Feedzirra::Feed.fetch_and_parse seems to return a hash.
Try for example
params = { :name => feed[:title] }
Assuming frontend is correct and REST resource publications is properly set up in Rails backend.
Controller should for example look like:
def create
# requesting the feed from passed url
feed = Feedzirra::Feed.fetch_and_parse(publication_params[:url])
# mapping feed keys to publication attributes
feed_to_publication_hash = { :name => feed[:title], anything else }
# instantiating new publication
#publication = Publication.new(publication_params.merge(feed_to_publication_hash))
...
end
private
def publication_params
params.require(:publication).permit(:url, everything else you need)
end
I am quite sure that even if that works it is not good practice. Usually you strife for Object Orientation, that is in this case one purpose per action.
But I don't know right now how to refactor fetching the feed and perhaps mapping the hash. Maybe it is a controller concern or something like that.
After reviewing the Feedzirra::Feed.fetch_and_parse the only option I see is that your publication_params[:url] contains something other than String. In that case fetch_and_parse returns a Hash of results (even if only one url was passed). Could you please check whether publication_params[:url].is_a?(String) is true.

confused and disoriented with paypal ipn

I am using this gem for payments in paypal https://github.com/tc/paypal_adaptive
I am very confused and disoriented with this gem. It has a poorly documented and is difficult for me to understand how to get the data from paypal on ipn response.
I hope this question will help more people having the same problem.
My steps are:
1º I send request to paypal from my orders_controller.rb with method preaproval_payment.
def preapproval_payment
preapproval_request = PaypalAdaptive::Request.new
data = {
"returnUrl" => response_paypal_user_orders_url(current_user),
"cancelUrl"=> cancel_payment_gift_url(#gift),
"requestEnvelope" => {"errorLanguage" => "en_US"},
"senderEmail" => "gift_1342711309_per#gmail.com",
"startingDate" => Time.now,
"endingDate" => Time.now + (60*60*24) * 30,
"currencyCode"=>"USD",
"maxAmountPerPayment" => "#gift.price",
"ipnNotificationUrl" => ipn_notification_url,
"ip" => request.remote_ip
}
preapproval_response = preapproval_request.preapproval(data)
puts data
if preapproval_response.success?
redirect_to preapproval_response.preapproval_paypal_payment_url
else
redirect_to gift_url(#gift), alert: t(".something_was_wrong")
end
end
2º These are the data of my request in my log console from command puts data :
{"returnUrl"=>"http://localhost:3000/en/u/maserranocaceres/orders/response_paypal", "cancelUrl"=>"http://localhost:3000/en/gifts/gift-1/cancel_payment", "requestEnvelope"=>{"errorLanguage"=>"en_US"}, "senderEmail"=>"gift_1342711309_per#gmail.com", "startingDate"=>2012-07-29 13:05:49 +0200, "endingDate"=>2012-08-28 13:05:49 +0200, "currencyCode"=>"USD", "maxAmountPerPayment"=>9, "ipnNotificationUrl"=>"http://localhost:3000/ipn_notification?locale=en", "ip"=>"127.0.0.1"}
3º I redirect to paypal page, and I make the payment on paypal successfully :D.
4º When payment is completed successfully, I am directed to:
http://localhost:3000/en/u/maserranocaceres/orders/response_paypal
I have response_paypal action in orders_controller.rb. It is GET action and my code for this action is:
def response_paypal
respond_to do |format|
format.html { redirect_to user_orders_url(current_user), :alert => "works fine return url"}
end
end
Up to this point everything works fine.
Now what I need is to get the data I received from paypal and save my database a new order if payment is successfully processed.
5º For this purpose I make a file in lib/paypal_ipn.rb and I add to this file the content from https://github.com/tc/paypal_adaptive/blob/master/templates/paypal_ipn.rb
# Allow the metal piece to run in isolation
require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
class PaypalIpn
def self.call(env)
if env["PATH_INFO"] =~ /^\/paypal_ipn/
request = Rack::Request.new(env)
params = request.params
ipn = PaypalAdaptive::IpnNotification.new
ipn.send_back(env['rack.request.form_vars'])
if ipn.verified?
#mark transaction as completed in your DB
output = "Verified."
else
output = "Not Verified."
end
[200, {"Content-Type" => "text/html"}, [output]]
else
[404, {"Content-Type" => "text/html"}, ["Not Found"]]
end
end
end
In my routes.rb I add:
match "/ipn_notification" => PaypalIpn
My 2 problems are:
a) I do not see that after making the payment this file to be fired and I can not see in my console data I get from paypal.
b) I want to send to paypal in my request, the id of object #gift for being able to recover later in paypal_ipn.rb and to save my database.
What am I doing wrong and how I can solve these problems?
Thank you
I haven't used that gem, but I've used PayPal IPN before. Here are some things you should check:
Do you have your PayPal account set up to use IPN? You must enable this setting on the account for this to work.
Have you verified that when you pass ipn_notification_url during the payment process, that it matches your "/ipn_notification" route?
For this to work, PayPal must be able to communicate directly with the server that is running this app. This means that typically, unless you have a custom setup on your local machine with dynamic DNS or something, that you will need to actually deploy this code to a server in order for PayPal to be able to communicate with your app. In other words, if this is running on http://localhost:3000, this will not work.
To answer your second question, how to recover #gift in order to record the fact it was paid in your database, I'm not entirely sure how to do it with this gem, but I'll tell you how I do it using ActiveMerchant - it is probably quite similar.
In your payment request to PayPal, you can pass in an invoice number. I believe the field is just called "invoice". Here you would pass the ID of the gift.
When PayPal notifies your app via IPN that the order was paid for, it will pass the invoice number back to you. Retrieve the #gift using this invoice number and then you can do what you need with it.
Here are the relevant parts of my working PayPal code, using the ActiveMerchant gem: https://gist.github.com/3198178
Good luck!

Resources