Is it possible to call a Rails 3 controller within Rack middleware? - ruby-on-rails

I want to use ExtDirect for a 3rd party extjs user interface in Rails 3. So I have started to update the active-direct gem to work with Rails 3. Here is the updated version: https://github.com/stonegao/active-direct
At the moment my modified active direct plugin/gem works with models. I'm able to do this in JavaScript:
App.namespace.Project.all({params},callback_function);
That's great.
Now I want to use some special Rails 3 controllers (that act like a service).
In my Extdirect JS is this:
App.mynamespace.MyProject_Controller_V1_workspaceController.getStatus
This response also comes to my extjs router. No I want call this controller action and get the response.
I can't use #app.call(env) with a changed request_uri because I have no match in routes.rb
Is it possible to call this controller action
Specification of extdirect: http://tinyurl.com/4y3nc44
Thanks skeller1

yes, it is!
just do something like this:
status,headers,response=ProjectsController.action("index").call(#env)
so you can call the index method of the ProjectsController.
beware: ExtDirect accepts all types in the HTTP_ACCEPT http header field.
so you can do a
#env['HTTP_ACCEPT'] = "application/json"
before your request to an action to set your wanted response type.

Related

AJAX + Rails: Should I Use a GET or a PUT When Creating a Route?

My question: When using AJAX within Rails, from a best practice standpoint, does the HTML verb that I use (e.g., get) to define a route matter? Is it OK to basically always use get?
Context: In my Rails App, I've built the following:
When a user selects an HTML checkbox, that triggers a JQuery listener that lives in a file inside of /app/assets/javascripts.
This .js file makes an AJAX call to a controller/action: foos#bar. My JS passes an ID into the action.
To route this request, I've added the following to routes.rb: get "/foos/bar" => "foos#bar". This tells my App which controller/action should process the AJAX call.
The controller/action handles this request just fine. The action grabs the ID as a URL parameter, updates the relevant model object, and finally returns back a 200 to the JS AJAX caller.
This all works great! No issues -- nothing to troubleshoot here.
My question is: In the example above, is it appropriate to define a get route within routes.rb to process this AJAX request? Or, is that bad practice? Should I instead be defining a put, since conceptually that is what I'm doing in this workflow (i.e., I'm updating an existing object)? I'm worried that, while this all works perfectly, I'm breaking some fundamental MVC routing standards.
If you are updating a resource it will most likely be a PATCH update, which means you aren't completely replacing the resource but are just updating it (this is why PATCH is the default HTTP method for updates in Rails, instead of PUT).
So, yes, you are violating RESTful conventions by using GET to update a resource. GET is only used to fetch a representation of a resource...without changing it in any way.

How param works in rails views

I have an old app running in rails 2.3.5
In customizing, I stuck when i find a param keyword being used in views
i.e in views I can see stuffs like
unless params[:fee_collection].nil?
can someone explain to me in what context is param keyword used in rail views rather than controllers
params is a hash that contains parameters sent with the HTTP request.
You can access to this object as well from your controller or from a view. Although, the convention is to access to an instance variable (defined in your controller, e.g : #fee_collection = params[:fee_collection]) from your view.
The params variable stores a hash which contains the http parameters received in the request to this route (controller#action)
If you have a UserController with the show method, you should receive the param[:id] to identify the resource you're looking for.
If you want to send parameters, it would be either via url in a GET or a data payload on a POST request, on the most common cases.

Why does params include details regarding controller and action?

Just curious, params are supposed to be hashes containing details regarding browser requests. But debug(params) returns
controller: controllername
action:actionname
.
.
.
Is there any specific reason it contains these key-value pairs?
params comes from three sources
The URL
The query string(GET)
The post data often by form submit(POST)
The controller name and action name comes from URL. Say the url is "article/123", Rails will know:
The controller is ArticlesController - Because "article" is the first part of url
The action is #show, because the request is GET and there is an ID
Any controller and action can be recognized once you have defined them in routes.rb. Remember you need to assign controller name and action for custom route?
I'm just speculating, but this might be from the days before Rails was built on Rack. Nowadays, you would just put these things into the Rack environment (and they are probably in there now). They are probably still there for backwards compatibility.
So you can query those in before/after/around filters, views (not the best practice), and methods shared between multiple controllers

How to route one URL to different controller/action with json data in Rails 3

I am writing server end of a JavaScript app. But engineer who write js and design APIs of this app decided all of ajax send json data to "one" URL, like this:
{
"id":"...",
"method":"method_name",
"params":{...}
}
So, I must provide different service for different "method_name". And the Rails router can not address this problem.
I can use the Object.send method routes the different service to different method, but, I want to distribute my code to different Controller class.
Can I parse the json data in route.rb file? Then route the /url/method_name to controller/action ?

Make Rails return response from other local URL

I want a /plan method to return a json object that's itself returned by another local (but belonging to another web app in java) URL (let's call it /plan2 for the sake of this question).
What I want is not a redirect but really to have /plan return the data as it is returned by /plan2, to which I'm appending a bunch of other keys. Since the request is local, would using Net::HTTP be overkill? What are my options, considering I'd also like to send an HTTP Accept header along.
Shooting in the dark here, but I am assuming that /plan belongs to public Rails app and the /plan2 is the url from another web app (maybe not even Rails) on the same server accessible by Rails app but not publicly available. If this is the case, then yes, you can get the response, but I would suggest rather OpenURI or Mechanize than Net::HTTP. If you put it in respond_to JSON format block then everything should be fine with Accept header also.
are you speaking of re-using functionality of another controller-method?
there is no standard way of doing this in rails. you could either put the common functionality into a module and include it this way, or use inheritance if the functionality is in another controller. if it's the same controller class, you could just call the method.
if it's a "private" url, how are you going to call it via http?!
I would suggest encapsulating whatever functionality /plan2 uses and simply re-use that in /plan1
But if you just want to get it to work...
class PlanController < ApplicationController
def plan1
plan2(extra_parameter_1: true, extra_parameter_2: 'hello')
end
def plan2(extra = {})
params.merge!(extra)
# Whatever your code was before...
end
end

Resources