Post request from external website to Rails App is not routed through - ruby-on-rails

I am trying to send data from an external website to a Rails app but the post request is not routed through correctly.
The Rails app has the route
post '/submit_text/' => 'activities#submitText', as: :submitText
The code of the corresponding controller action is
before_filter :submitText
protect_from_forgery :except => :submitText
def submitText
puts "in submitText"
puts params[:text]
puts "end of submitText "
end
I am trying to send data from an external website to the Rails app like this
<form action="https://todo-list-study.herokuapp.com/submit_text/" method= "post">
<textarea name="response[text]" rows="25" cols="75" id="answer_text">
</textarea>
<input type="submit" name="Submit" value="test" onclick="recordAnswer()">
</form>
When I submit data from the external website, the Rails app receives it but it does not pass it on to the specified controller action. Here is what happens according to the Heroku log file:
heroku[router]: at=info method=POST path="/submit_text/" host=todo-list-study.herokuapp.com request_id=fee72511-ad1e-41c3-ae4c-d4b3395e6afd fwd="24.7.71.184" dyno=web.1 connect=1ms service=19ms status=500 bytes=1754 protocol=https
Unfortunately, that is all that happens. Given that the put statement at the beginning of the method is not executed I conclude that it is not being called. This happens even though both the Rails app and the external website run on the HTTPS protocol.
What can I do to fix this?

The router is finding an action for that call, otherwise it would have responded with a 404 instead of a 500, which indicates that there's an internal error.
Assuming that you're not trying to send back a response with content back to the client, try adding a call to render so that your controller sends back a response instead of trying to find a view template to render, which is where I'm guessing the issue is.
For example, try updating your code to:
def submitText
puts "in submitText"
puts params[:text]
puts "end of submitText "
render nothing: true
end

Related

ActionController::InvalidAuthenticityToken on updating the password

I have a Ruby On Rails application. Now, I started getting ActionController::InvalidAuthenticityToken error while updating password in admin_controller.
CSRF token is present in layout.
Earlier it was working, today when I get a warning from google to change password, I tried to update the password & got this error.
Below is the request:
Started PATCH "/admin/password/change" for 127.0.0.1 at 2020-07-25 22:05:38 +0530
Processing by Admin::PasswordsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"osXhNhqJZ9qXeJ4F2BXrJvOTflrG5G3MGPl7yuOa4Y8PoqIXKEVe17bqO5u9nGYG2Bn0Zun2U9mOR4/uxNajsg==", "current_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}
I am using devise-4.3 for authentication.
If tried to update the password 3-4 time, then it works but not each time.
I believe I should refresh the token, turbolinks might be creating an issue.
Every other post/patch request is working.
Ruby-2.4.0, Rails-5.1.4
Go to the controller that’s generating the error, and paste following line of code above all the defined functions:
skip_before_filter :verify_authenticity_token, :only => :create
OR
protect_from_forgery with: :null_session
save it then restart the server!
Let me know if this works for you!
Need to Hard reload the page/disable turbolinks, so I added the following in link_to
<%= link_to 'Change Password', change_admin_password_path, data: { turbolinks: false }) %>
Now the complete page reload is happening and I am able to update the password.

Problems using controller on postgres DB on AWS RDS from Heroku app

I've setup a postgres DB to use postgis for a Heroku App I have, running on Ruby on Rails.
My steps have been:
Create RDS DB running pg 9.4.9
Enable rds.force_ssl on RDS Parameter Group.
Backup and load my Heroku database into new postgres DB.
Download Amazon RDS CA Certificate and place it under config/amazon-rds-ca-cert.pem.
Add gem 'activerecord-postgis-adapter' to my gem file.
Update database.yml file to the below:
:
default: &default
adapter: postgis
encoding: unicode
pool: 5
production:
<<: *default
encoding: utf8
database: <%= ENV['RDS_DB_NAME'] %>
username: <%= ENV['RDS_USERNAME'] %>
password: <%= ENV['RDS_PASSWORD'] %>
host: <%= ENV['RDS_HOSTNAME'] %>
port: <%= ENV['RDS_PORT'] %>
postgis_extension: postgis
schema_search_path: public,postgis
Update DATABASE_URL parameter on Heroku to postgres://myuser:mypassword#mydbinstance.xxxxxxxxxxx.us-west-2.rds.amazonaws.com/mydbname?sslmode=verify-full&sslrootcert=config/amazon-rds-ca-cert.pem
Additional steps in this very helpful question: Enabling Ruby PostGIS support on Heroku
Push updated code and access my App.
When I try to access the database to verify connectivity it works ok:
nc -zv mydbinstance.xxxxxxxx.us-west-2.rds.amazonaws.com 5432
Connection to mydbinstance.xxxxxxxxx.us-west-2.rds.amazonaws.com 5432 port [tcp/postgresql] succeeded!
and when I navigate on the app I am able to see the results of queries. However, when I try to use a model that uses postgis, somehow my connections don't work correctly. Here's my Controller's code, which stores lat, lng pairs with bus stop information, and finds the ones close to a point given in parameters:
class TransitStopsController < ApplicationController
def create
end
def show
#transit_stop = TransitStop.find(params[:id])
#transit_routes = #transit_stop.transit_routes
end
def get_nearby_stops
radius_in_meters = params[:radius_in_meters].nil? ? 3219 : params[:radius_in_meters]
#nearby_stops = TransitStop.close_to(params[:lat], params[:lng], radius_in_meters)
end
end
My Model:
class TransitStop < ActiveRecord::Base
has_many :transit_stops_transit_routes, foreign_key: "onestop_id", class_name: "TransitStopsTransitRoute"
has_many :transit_routes, through: :transit_stops_transit_routes, foreign_key: "route_onestop_id", class_name: "TransitRoute"
validates_uniqueness_of :onestop_id
#Get transit stops close to a given lat, lng pair. Default distance = 2 miles
scope :close_to, -> (lat, lng, distance_in_meters = 3219) {
where(%{
ST_DWithin(
ST_GeographyFromText(
'SRID=4326;POINT(' || transit_stops.lng || ' ' || transit_stops.lat || ')'
),
ST_GeographyFromText('SRID=4326;POINT(%f %f)'),
%d
)
} % [lng, lat, distance_in_meters])
}
end
and my View (get_nearby_stops.jbuilder):
json.nearby_stops #nearby_stops do |transit_stop|
json.region_id transit_stop.region_id
json.lat transit_stop.lat
json.lng transit_stop.lng
json.onestop_id transit_stop.onestop_id
json.name transit_stop.name
json.osm_way_id transit_stop.osm_way_id
json.osm_way_id transit_stop.served_by_vehicle_types
json.timezone transit_stop.timezone
json.wheelchair_boarding transit_stop.wheelchair_boarding
json.created_or_updated_in_changeset_id transit_stop.created_or_updated_in_changeset_id
json.transit_routes transit_stop.transit_routes
end
Routes.rb has line added to access method:
get 'transit_stops/get_nearby_stops' => 'transit_stops#get_nearby_stops'
When I try to access this via: https://myherokuapp.herokuapp.com/transit_stops/get_nearby_stops.json?lat=-122.49766&lng=37.71677
All I get is a message:
Application Error
An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details.
When I look at my heroku logs all I see is a timeout error:
app[web.1]: Processing by TransitStopsController#get_nearby_stops as JSON
app[web.1]: Parameters: {"lat"=>"-122.49766", "lng"=>"37.71677"}
heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/transit_stops/get_nearby_stops.json?lat=-122.49766&lng=37.71677" host=myherokuapp.herokuapp.com request_id=1e081fdf-d0ce-4000-a6b4-4e75c176b8a2 fwd="10.0.0.1" dyno=web.1 connect=0ms service=30001ms status=503 bytes=0
The AWS Error Logs show nothing.
The strange thing to me is that I am able to perform the same query by connecting to Heroku's rails console:
irb(main):001:0> TransitStop.close_to(-122.49766,37.71677,5000)
=> #<ActiveRecord::Relation [#<TransitStop region_id: 1, lat: #<BigDecimal:7fe69f6c95c0,'-0.122504106E3',18(18)>...
...
etc
So at this point I don't understand what's causing this controller to fail only when I access it through my view, but not through console? Should the database url be different if I use postgis methods?
Any help would be highly appreciated.
EDIT: I've tested the show method of my controller, and it works ok:
app<a class="jive-link-external" href="http://web.1">http://web.1</a>: Started GET "/transit_stops/s-9q8ys6puje-655johnmuirave.json" for 159.16.243.2 at 2016-11-12 19:55:16 +0000
app<a class="jive-link-external" href="http://web.1">http://web.1</a>: Processing by TransitStopsController#show as JSON
app<a class="jive-link-external" href="http://web.1">http://web.1</a>: Parameters: {"id"=>"s-9q8ys6puje-655johnmuirave"}
herokurouter: at=info method=GET path="/transit_stops/s-9q8ys6puje-655johnmuirave.json" host=myapp.herokuapp.com request_id=15814367-5235-484b-bff9-7727a2349dd0 fwd="10.0.0.1" dyno=web.1 connect=0ms service=329ms status=200 bytes=1385
app<a class="jive-link-external" href="http://web.1">http://web.1</a>: Rendered transit_stops/show.json.jbuilder (107.3ms)
app<a class="jive-link-external" href="http://web.1">http://web.1</a>: Completed 200 OK in 217ms (Views: 6.7ms | ActiveRecord: 207.4ms)<br class="jive-newline" />
Which to me translates to perhaps there being some problem in the database to perform the query I'm doing? The query itself should be fast, as when I test it in console I always get a response almost immediately, but perhaps something about the configuration of the database needs to be changed?
Just for other people to see, my problem was that after the query, my view was also producing several additional queries, because the field
transit_stop.transit_routes
is a relationship to a different table. Thus, for every resulting stop the database was performing many other queries for every result I got. Since my query was returning several hundred results, the final view performed several hundred additional queries which caused a lot of overhead to my db.
To detect this I updated log_statement = all to my db parameter group, so that I could see all activity coming into the database. I've updated my query to make it more efficient by reducing the number of results to only the n nearest ones, with a maximum of 10, as I don't really have any use on getting so many results.

Getting rails error when using Spaceship::Tunes

In a rails app I am running:
54 def itunes_all_apps
55 begin
56 Spaceship::Tunes.login(params[:itunes_username], params[:itunes_password])
57 apps = Spaceship::Tunes::Application.all
58 render json: apps.to_json, status: 200
59 rescue => e
60 render json: {error: e}.to_json, status: 500
61 end
62 end
It returns a status 500 error with no other information every time.
However, if I change this around slightly, for example getting teams (note, from Spaceship, not Spaceship::Tunes) this works fine:
def itunes_all_apps
begin
spaceship = Spaceship.login(params[:itunes_username], params[:itunes_password])
teams = spaceship.teams
render json: teams.to_json, status: 200
rescue => e
render json: {error: e}.to_json, status: 500
end
end
I'm not using any fast file or or config or anything. Just passing in a username and password via an api call and trying to get a response back. I'm new to rails so it may be my implementation of the Spaceship examples provided.
Using spaceship 0.36.1 gem (the latest)
I've pored through the docs to no avail. Grasping for any leads on what I'm doing wrong.
http://www.rubydoc.info/gems/spaceship/Spaceship/Tunes
https://github.com/fastlane/fastlane/blob/master/spaceship/docs/iTunesConnect.md
Someone suggested I run these two commands in irb, which I did, and they worked perfect!
Spaceship::Tunes.login('myAppleId', 'myPassword')
Spaceship::Tunes::Application.all
So it's not an iTunes account problem or credentials problem (because it works in irb), routes problem (because I ran both rails methods above with same route), or params problem (because I ran both rails methods above with same param names).
I really appreciate any suggestions. Thanks.
Edit:
Commenting out begin, rescue, and rending the error, the stack trace is as follows:
2016-10-24T17:47:34.974650+00:00 app[web.1]: Started POST "/api/v1/users/13/itunes_all_apps" for 162.237.102.13 at 2016-10-24 17:47:34 +0000
2016-10-24T17:47:34.977478+00:00 app[web.1]: Processing by Api::V1::UsersController#itunes_all_apps as JSON
2016-10-24T17:47:34.977521+00:00 app[web.1]: Parameters: {"itunes_username"=>"myCorrectUsername", "itunes_password"=>"[FILTERED]", "team_id"=>"myCorrectTeamId", "id"=>"13", "user"=>{}}
2016-10-24T17:47:35.629629+00:00 heroku[router]: at=info method=POST path="/api/v1/users/13/itunes_all_apps" host=myHerokuApp.herokuapp.com request_id=002d906d-354e-4633-8b54-71aa5181e3a7 fwd="161.237.102.13" dyno=web.1 connect=2ms service=657ms status=500 bytes=259
2016-10-24T17:47:35.619597+00:00 app[web.1]: Completed 500 Internal Server Error in 642ms (ActiveRecord: 0.0ms)
2016-10-24T17:47:35.620430+00:00 app[web.1]:
2016-10-24T17:47:35.620432+00:00 app[web.1]: IOError (not opened for reading):
2016-10-24T17:47:35.620434+00:00 app[web.1]:
2016-10-24T17:47:35.620433+00:00 app[web.1]: app/controllers/api/v1/users_controller.rb:58:in `itunes_all_apps'
It seems that Spaceship::Fastlane::Application does not implement as_json method and the default as_json touches some IO object, which cannot be represented as json.
My suggestion would be to create JSON serializer. You could use active_model-serializer, but if you do not want to create a dependency just for one object, then you can create your own serializer.
class SpaceshipApplicationSerializer
attr_reader :spaceship_applications
def initialize(spaceship_applications)
#spaceship_applications = spaceship_applications
end
def as_json(options = {})
spaceship_applications.each_with_object([]) do |spaceship_application, memo|
memo << object_as_json(spaceship_application)
end
end
def object_as_json(object)
attributes.each_with_object({}) do |attribute, memo|
memo[attribute] = object.send(attribute)
end
end
def attributes
[
:apple_id,
:name,
:vendor_id,
:bundle_id,
:last_modified,
:issues_count,
:app_icon_preview_url
]
end
end
# In your controller
def itunes_all_apps
begin
Spaceship::Tunes.login(params[:itunes_username], params[:itunes_password])
apps = Spaceship::Tunes::Application.all
render json: SpaceshipApplicationSerializer.new(apps).to_json, status: 200
rescue => e
render json: {error: e}.to_json, status: 500
end
end
EDIT:
Yes, the classes return an array, but the actual objects in array don't play nicely with json. It's hard to say if the problem is with the library - on one hand Spaceship::Tunes::Application not returning a proper json representation is a missing feature, but if the to_json raises an exception (a method the class responds to) - then I would say that is a bug.
Creating your own serializer to build json representation the way you want it - is a common pattern.

Rails: redirect_to 'myapp://' to call iOS app from mobile safari

I have a native iOS app that can be called from Mobile Safari in iOS via myiosapp://. I also have a simple Rails app that SHOULD redirect to the native app when the request is coming from mobile. This is where I am I having problems - I can't redirect_to 'myiosapp://
I want to describe this problem as short as possible, so I made a sample app that shaves away the irrelevant information, but replicates the same problem.
Here's my routes.rb:
MyRailsApp::Application.routes.draw do
root :to => 'redirect#index'
end
And here's redirect_controller.rb:
class RedirectController < ApplicationController
def index
if request_from_mobile?
redirect_to "myiosapp://"
else
redirect_to "/default.html"
end
end
private
def request_from_mobile?
request.user_agent =~ /Mobile|webOS/
end
end
Whenever I run rails server and go to localhost::3000, I get this:
Started GET "/" for 127.0.0.1 at 2012-09-21 14:00:52 +0800
Processing by RedirectController#index as HTML
Redirected to motionapp://
Completed 302 Found in 0ms (ActiveRecord: 0.0ms)
[2012-09-21 14:00:52] ERROR URI::InvalidURIError: bad URI(absolute but no path): motionapp://
/Users/dev/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/uri/generic.rb:1202:in `rescue in merge'
/Users/dev/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/uri/generic.rb:1199:in `merge'
/Users/dev/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpresponse.rb:220:in `setup_header'
/Users/dev/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpresponse.rb:150:in `send_response'
/Users/dev/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpserver.rb:110:in `run'
/Users/dev/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
Before posting this, I've already seen a number of similar problems, but none seemed to be more specific to how I can implement this in Rails:
How to redirect from Mobile Safari to Native iOS app (like Quora)?
iphone web app to automatically redirect to app
Turns out there's a simple solution that is enough for the context of my app as of the moment. I just needed to handle the redirect in javascript. Other solutions are still welcome. :)
<html><head>
<script type="text/javascript">
var userAgent = window.navigator.userAgent;
if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i)) {
window.location = "myiosapp://"
}
</script>
</head>
<body>
Some html page
</body>
</html>

Devise with mobile mime type, 401 only displays flash message

I have a Rail 3.2.2 app with Devise 2.0 that I've begun to incorporate mobile views with. I'm using a before_filter in my application_controller.rb to use the mobile layout as follows:
before_filter :adjust_format_for_mobile
private
def adjust_format_for_mobile
if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
request.format = :mobile
end
end
I have the mime type defined in initializers/mime_types:
Mime::Type.register_alias "text/html", :mobile
Whenever I attempt to access the root_path as defined in routes.rb:
root :to => "wells#index"
(which is protected via before_filter :authenticate_user!)
All that is rendered is the Devise flash message (no HTML whatsoever):
You need to sign in or sign up before continuing
I have the necessary mobile layout, what am I missing here? The behavior on the desktop version is that you're redirected to the new_user_session_path, why is that not the case here?
EDIT:
The console log is as follows:
Started GET "/" for 127.0.0.1 at 2012-03-21 17:07:35 -0500
Processing by WellsController#index as HTML
Completed 401 Unauthorized in 0ms
Additionally, this only occurs with that particular path (the root path). If I manually go to users/sign_up or users/sign_in it works perfect. I can then log in and everything works fine.
Found a wiki on the process:
How To: Make Devise work with other formats like mobile, iphone and ipad (Rails specific)

Resources