I have 2 apps running on my localhost on port 3000 and 9000 (rails 2 and sinatra app).
I have set up a controller in the rails app (without any specific model or view) in app/controllers/finance_service.rb
class FinanceServiceController < ApplicationController
def after_token_create
p "after token create function: #{params.inspect}"
end
end
and had set up a route like so :
map.finance_service '/finance_service' , :controller => "finance_service", :action => "after_token_create"
and When I access it on the url http://localhost:3000/finance_service
I get error on template missing, but that's fine because it means the route is working (I am using it as a service api to the another app).
when trying to access the method from the other app using httparty gem like so :
HTTParty.post("http://localhost:3000/FinanceServiceController/after_token_create", :body => post_params)
I get an error on the rails app-
myapp/public/404.html (method_not_allowed)
Also tried from advanced Rest client app, and I get the same error.
Shouldn't the request be like this? since the route matcher is /finance_service
HTTParty.post("http://localhost:3000/finance_service", :body => post_params)
Related
I started Ruby on Rails few days ago, and I'm struggling with routing.
Indeed, I would like to make a post request through my routes.rb, but I keep having a
No route matches [GET] "/orders/refresh"
error.
Here is my routes.rb :
# frozen_string_literal: true
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
get '/orders', to: 'orders#index'
get '/orders/active(/:q)', to: 'orders#active'
post '/orders/refresh', to: 'orders#refresh'
end
and here is my controller (orders_controller.rb) :
# frozen_string_literal: true
class OrdersController < ApplicationController
def index
#orders = Order.order(:departure_date).all
render json: #orders.to_json
end
def active
if !params[:q]
#orders = Order.order(:departure_date).where(active: true)
else
#orders = Order.order(:departure_date).where("reference = ? OR client_name = ? OR departure_city = ? OR arrival_city = ?",
params[:q], params[:q], params[:q], params[:q])
.where(active: true)
end
render json: #orders.to_json
end
def refresh
response = RestClient.get 'https://wakeo-technical-test.s3.eu-west-3.amazonaws.com/api.json'
json = JSON.parse response
if !json.nil?
json.each do |order|
old_order = Order.find_by(reference: order["client_number"])
if !old_order.nil?
old_order.update(departure_date: order["dep_time"])
old_order.update(arrival_date: order["arr_time"])
old_order.update(client_name: order["company"])
old_order.update(departure_city: order["dep_city"])
old_order.update(arrival_city: order["arr_city"])
end
end
else
puts "error seeding external API"
end
end
end
From what I have understood, it seems like RoR will try to find a GET request for that specific URL, and since it won't find any, it will throw that error. How could I make that request be a POST for Rails ?
Also, I would appreciate any suggestion about how I should use ActiveRecord Querying, I'm pretty sure I could do it better here.
Thanks, have a great day !
EDIT : Here is the list of different routes my app seems to be capable of, including my POST.
Routes and error
The most common reason you unexpectly get GET requests instead of PUT, PATCH, POST or DELETE is that you are using link_to 'Something', '/some_path', method: :post and you broke the Rails Unobtrusive Javascript Driver (Rails UJS):
Because submitting forms with HTTP methods other than GET and POST
isn't widely supported across browsers, all other HTTP methods are
actually sent over POST with the intended method indicated in the
_method parameter. Rails automatically detects and compensates for this.
Rails does that with a JavaScript event handler attached to any link with the data-method attribute. But if you broke that functionality the browser will just perform its default action which is sending a GET request when the user clicks a link.
This problem usually boils down to one or more of:
Your javascript is throwing an error which halts script execution (use the browser console to find the error, make it suck less).
Rails UJS is not included in your assets pipeline or webpacker packs and thus not in the page.
The quick and easy solution to sidestep the problem is by using button_to which actually creates a form and does not require any JavaScript trickery. After all forms can send POST requests. And by just passing a _METHOD hidden field Rack will treat the request as any other HTTP verb.
button_to 'Something', '/some_path', method: :post
But in the long run you should probably fix the problem if you want to use any of the features of Rails UJS.
Your routes.rb is expecting a POST request to /orders/refresh routes, but apparently you are testing with a GET request.
Try changing your routes.rb:
Rails.application.routes.draw do
# ...
get '/orders/refresh', to: 'orders#refresh'
end
... or change your request to a POST request. If you are using Rails forms, you must do something like this:
form_with(url: "/orders/refresh", method: "post")
Ok, I think I figured it out.
It might be because when I hit /orders/refresh directly in my web browser, it will try to find a GET corresponding to the request.
I managed to make POST using a client like Postman, and everything works fine.
Thank you for your help !
I'm trying to figure out how to send transactional email from my Rails 4 app.
I have found tutorials for the postmark gem, but I'm struggling to close the gaps between what's assumed in the tutorials (where to do the suggested steps!) and what I know.
I have installed both the ruby and the rails gems in my gemfile:
gem 'postmark-rails', '~> 0.13.0'
gem 'postmark'
I have added the postmark config to my config/application.rb:
config.action_mailer.delivery_method = :postmark
config.action_mailer.postmark_settings = { :api_token => ENV['POSTMARKKEY'] }
I want to try to make and use email templates in postmark.
The instructions in the postmark gem docs say I need to:
Create an instance of Postmark::ApiClient to start sending emails.
your_api_token = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
client = Postmark::ApiClient.new(your_api_token)
I don't know how to do this step? Where do I write the second line? I have my api token stored in my config. I don't know how to make an instance of the postmark api client.
Can anyone point me to next steps (or a more detailed tutorial)?
After you have installed the gems, you need to create a Mailer. I presume you have already configured the API keys etc. in the correct manner, so I will concentrate on actually sending out a templated / static email.
Lets create app/mailers/postmark_mailer.rb file with the following contents.
class PostmarkMailer < ActionMailer::Base
default :from => "your#senderapprovedemail.com>"
def invite(current_user)
#user = current_user
mail(
:subject => 'Subject',
:to => #user.email,
:return => '74f3829ad07c5cffb#inbound.postmarkapp.com',
:track_opens => 'true'
)
end
end
We can then template this mailer in the file app/views/postmark_mailer/invite.html.erb Let's use the following markup to get you started.
<p>Simple email</p>
<p>Content goes here</p>
You can write it like any other .html.erb template using tags, HTML and alike.
To actually send this email out you need to place an action in your controller, in the following manner.
PostmarkMailer.invite(current_user)
Alternatively, if you want this email to be sent upon visiting homepage, it would most likely look like this:
app/controllers/home_controller.rb with content
class HomeController < ApplicationController
# GET /
def index
PostmarkMailer.invite(current_user)
end
end
and corresponsing route
config/routes.rb with content
root :to => 'home#index'
I hope this answers your question.
I am working on application using RhoMobile 4.0. I want to know, how to connect to web service in rhomobile 4.0 without rhoconnect. Need to do http post and get.
Using RhoMobile, you can using the usual AJAX methods to reach a webservice to get or post data.
Additionally you can use the RhoMobile Network API from Ruby or from JavaScript to call a webservice, registering a callback.
For example in Ruby you can have this code in a controller:
def getData
#Perform an HTTP GET request.
getProps = Hash.new
getProps['url'] = "http://<my_url>/Json/Server/GetDada?username=admin&password=pass"
getProps['headers'] = {"Content-Type" => "application/json"}
Rho::Network.get(getProps, url_for(:action => :get_callback))
render :action => :transferring
end
def get_callback
if #params['status'] == "ok"
get_result = Rho::JSON.parse(#params['body'])
puts "**** Parsed it" #{#params['body']}"
# Do something with the data
end
end
I am working on a rails application and added a simple login system according to a book.
I created the controller admin:
rails generate controller admin login logout index
It added the following routes to routes.db
get "admin/login"
get "admin/logout"
get "admin/index"
I can got to http://localhost:3000/admin/login there is no problem at all.
But when I try to login I get: No route matches "/admin/login"!
Now, the first confusing part is that the "login" method of my AdminController is not executed at all.
The second confusing part is that this code works like a charm - redirects everything to /admin/login:
def authorize
unless User.find_by_id(session[:user_id])
flash[:notice] = "you need to login"
redirect_to :controller => 'admin', :action => 'login'
end
end
Sidenotes:
I restarted the server several times.
I tried a different browser - to be sure there is no caching problem.
Try
match "/admin/login" => "admin#login"
match "/admin/logout" => "admin#logout"
match "/admin/index" => "admin#index"
(notice the leading /)
As an aside, unless you're creating a login system to learn about Rails and/or authentication, you're probably better off using something like Devise.
Following on from David Sulc's answer:
You're defining the routes as get requests, meaning to go to them you must perform a GET /admin/login request which is basically what happens when you type the URL into your address bar or follow a link that uses it.
However when you try to use these URLs in a form, the form does a POST request and because you've defined all of these as get-only requests, Rails will not be able to find a compatible route.
I definitely agree with David that you should look at an alternative system such as Devise.
As part of the deployment process for our rails 2.3 app, I'd like to save static versions of our error pages to the public folder. How do I get the rendered output of a controller's action without visiting the web page? I know it can be done because the functional tests do it - if I say
get :errors, :id => 404
then the body is in #response.body. I suppose I could just copy the code out of ActionController::TestCase, but I'm hoping that there's a simpler way to do it.
In the end I did just go into ActionController::TestCase, and this is what I dug out:
def get_content host, path, filename
request = ActionController::Request.new 'HTTP_HOST' => host,
'REQUEST_URI' => path,
'REQUEST_METHOD' => 'GET',
'rack.input' => '',
'rack.url_scheme' => 'http'
controller = ActionController::Routing::Routes.recognize(request).new
response = ActionController::Response.new
controller.process request, response
return response.body
end