Internal redirection in Padrino - ruby

Is there a way to internally redirect in Padrino? I am writing a RESTful service, no HTML response of browser client.
I have a resource, lets say, xyz.
MyApp.controllers :xyz
I have two routes in a controller:
put :index, :with => :xyz_id do...end
and
get :show, :map => '/xyz/:xyz_id' do...end
Now to simplify (and centralize) view (which is a JSON document) creation, I want to just internally redirect the control so that it processes the :show method after creating the resource. Hence, for a client of the service, PUT /xyz/1234 will create a new resource and return the same and GET /xyz/1234 will return the resource if it exists.
Is there a way to INTERNALLY (not a 302 response sent to the client) redirect to get :show method from the put :index method (after creating the resource)? Something like:
redirect (:xyz, :index, {:xyz_id => '1234'})

First of, you can put logic behind the showing data into separate function that you can call from both GET and PUT routes. If you really want to pass processing to a different route, you can do it with rack's call method:
put '/foo' do
# putting related stuff
call env.merge('REQUEST_METHOD' => 'GET')
end

Related

Redirect to another model's index action, and hence view index.erb - Rhomobile

I am developing a Rhomobile application,on submit of a POST method, i am going to my 'Model 1' action, after execution of my action i want to redirect to another model's (Model 2) Index action and list the data.
I am from a Rails background, there i would have used URL, any similar concept exists here or any solution.
i tried, but it didn't worked for me render :controller => :model2, :action => :index
Please Note: I have never used rhodes and all of this information was acquired by simply reading the API documentation and taking a look at the source code.
According to the documentation You should be able to deal with this in a very railsy fashion eg
def some_action
redirect controller: :model2, action: :index
end
Seems the only caveat is if this redirection is to happen in a callback function. In this case the redirection should be handled by the WebView instead e.g.
Rho::WebView.navigate(url_for(controller: :model2 action: :index))
Source for Rho::RhoController#redirect supports these statements in the documentation.
Additionally as you might notice above it appears that Rho has ported a lot of the rails like helpers including url_for

How do I add custom logging for which route is satisfying a request in Sinatra?

I'm working on a Sinatra app that has a bunch of routes of all sorts. I'd like to add some custom logging that logs the params of the get or post call that ends up generating the response for the request. I realize I could subclass the get/post definition to wrap the block with a logging call. But I suspect there is a more appropriate approach.
You can use Sinatra's before hook in your controller, and print out some information contained on the request
before do
if request.request_method == :get || request.request_method == :post
puts request.path_info, params.inspect # check out the request variable for more info you might like to ouput
end
end

rails not routing https

The following rails routes.rb file
resources :aggregators, :constraints => { :protocol => "https"} do
collection do
get :confirm
post :send_sms
end
member do
post :confirmed
post :failed
post :cancelled
end
end
is not being called. When a form calls one of these actions,
<%= form_for(#aggregator) do |f| %>
the user gets bounced to the root page of the application. In comparing with and without the constraints, the non-https activity picks up
Started POST [...]
Processing by AggregatorsController#create as HTML
whereas the https version
Started POST [...]
Processing by AggregatorsController#index as HTML
So clearly the routing is missing the create action. (the bouncing back to home is an applicationController method which aplies a policy on the index action) I assumed it would be an integral part of resources. What am I doing wrong? Better yet I only want to invoke https on specific actions and would like to keep the focus on new, create and confirm...

Why am I getting a 405 on a POST request for JSON?

So I've got a Padrino app with a controller that looks roughly like this (simplified for brevity):
App.controllers :questions do
get :index, :with => :id, :provides => [:html, :json] do
# Stuff
end
post :index, :with => :id, :provides => [:html, :json] do
# Other stuff
end
end
If I hit "questions/1" in my browser, I see the HTML page for the given question. If I hit "questions/1.json", I see the JSON representation of the question. Exactly like I'd expect.
Now, if I submit a POST request to "questions/1" via a web form, it works. But if I try to send a POST request to "questions/1.json" (signaling that I want the response in JSON format—or at least that's how I thought it worked), I get a 405 Method Not Allowed.
I'm guessing there's something basic I'm misunderstanding here. What am I missing? More importantly, how should I define a route to accept POST requests and provide either HTML or JSON responses?
Well, I'm not really sure why this was happening; but for now I've gotten around the issue by setting the "ACCEPT" header in my POST request to "application/json" instead of tacking ".json" onto the end of the URL (and upon my limited internet research, this may be the preferred approach anyway).

Backbone JS and Ruby on Rails CRUD issue

This looks like an issue to me. Normal way Backbone works is using same URL and GET, POST, PUT and DELETE. But obviously:
1) All but POST methods need an ID either in URL or in request body
2) DELETE request can not contain body or some servers ignore body
So how can you make let's say a Ruby on Rails server app successfully work with Backbone without need to hack Backbone such as model.destroy() needs to have ID in the URL? And, as our RoR developer is telling me, normal way to do routes for PUT is to also have an ID in the URL?
There are 5 routes you need to implement to make use of backbone's default sync behavior. For a resource user, they are:
GET /user/ // Get a list of users
GET /user/:id // Get a single users by id
POST /user/ // Create a new user
PUT /user/:id // Update an existing user by id
DELETE /user/:id // Delete an existing user by id
I'm not very familiar with Ruby on Rails, but glancing at their documentation you could fulfill this specification with something like:
match "/user/" => "users#all", :via => :get
match "/user/:user_id" => "users#one", :via => :get
match "/user/" => "users#create", :via => :post
match "/user/:user_id" => "users#update", :via => :put
match "/user/:user_id" => "users#delete", :via => :delete
You should not have to hack Backbone for it to work with RoR. Backbone is smart enough to know (to a certain extent) what URL and what method it should use.
For example, for the initial fetch of a model, if you set url to '/tasks', it will do a GET request to '/tasks/id'. When you change that model, and call model.save, it will do a PUT request to '/tasks/id'. When you call model.destroy, it will send a DELETE request (with an empty body)
The one thing you do have to consider is the CSRF token. I suggest you include backbone-rails in your Gemfile. It includes some JavaScripts to help with Rails/Backbone integration.

Resources