How does ruby on rails map http request to handler function? - ruby-on-rails

I am new to RoR, so please forgive me if this is a stupid thing to ask.
I was looking into routes.rb file and found these two lines:
get "question/question"
get "question/answer"
But there was no mention of the functions they are mapped to.
I tried to look how they are mapped to the functions and in all the tutorials or reference docs I found on net, requests were hashed to function names.
So I was not able to understand the routing in this case. Can someone give names of some files to look into or some documents suitable for beginners which can explain routing clearly, removing the magical part?

Look at the QuestionsController and the question and answer methods.
See these routing docs for details on how routing works for these types of paths.

Allow defaults for values when possible.
These lines
get question/question
and
get question/answer
means respond to get requests that use a url with question/question or question/answer to be processed by the:
question controller and the question method
question controller and the answer method
You may be more used to working with constructs like:
get 'users/change_district/:district_id' => "users#set_district", :as => 'change_district'
which allow you to specify which controller (users) and which action (set_district)
If, however, you omit some parts then the router will use what you give and use defaults for anything not specified.

Related

how to fetch the route i.e path of my current api in routes.rb file

I'm new to rail. I have few clarifications, which I have listed below.
I have referred many links and stack overflow questions, everywhere it's mentioned to use request and fetch the details regarding the path, controller, action etc. but if I use request in my routes.rb it throws undefined local variable or method error.
I used constraints in my routes.rb and from there it calls a method matches? from a class where dynamic constraints are defined inside lib/constraints directory. In here the matches?(request) receives a parameter named request, which has details about current route, from where the parameter value is sent?, I have this doubt because while using this method inside routes.rn in constraint(ClassName) I'm not sepecifying the method name (matches?) or the parameter request
I would like to know the working of things behind the scene.
Thank You
Are you looking for it
request.url
# => "http://localhost:3000/lists/7/items"
request.path
# => "/lists/7/items"
If you have URIs:
localhost:3000/users/:id
localhost:3000/users
localhost:3000/users/new
....
You can do something like
rake routes | grep user
in order to get only those that contain user in its path name.
Hope this helps..
conventionally you don't access the current path in the routes.rb, at least as how it seems you're asking to access it. There are a number of different matching methods and techniques used in the rails router that serve the utility I imagine your looking for.
Here's a link to the docs: https://guides.rubyonrails.org/routing.html
Can you share exactly why you want to access the curret route in the routes.rb file?

Rails 3.1 Routing

I'm trying to route a particular object's show method to the root path of my app, but I'm having trouble routing it anywhere at all for that matter. So I guess this break down into two questions:
If I wanted /pages/2 for example to go to the root path, how would I do this?
Also, if I wanted to make the url take a name or some attribute (eg. /username would find_by_username and show the correct page) how would I do this?
I've looked at a couple railscasts and the rails guide on routing, but I seem to be missing something...
Any help would be much appreciated.
First of all, I should warn you. Because you want to break down REST pattern. REST was well designed by clever folks and if you want to redefine some of it's functionality - so you have some incorrect logic in your App design.
Now to answer your question:
1. You can try something like this:
match "pages/:id", redirect {|params| "your_root_url" if params[:id] == 2}
2. Look at to_param documentation for more detail.
I hope i helped you alittle

How to stick with REST?

I'm basically putting together an app that does a super simple question => answer test in an attempt to learn more about rails.
ie:
Question: "What's your dog's name?"
Answer: "Doggington"
I have a Question model with two simple attributes:
question:string
correct_answer:string
My struggle here is how do i apply REST principals to this -- specifically, when i am checking a user's input(answer) to see if he got the question right or not.
I'm not sure if i should do something like modify the "show" method (or any other action) to accept values for answer posted to it... and it SEEMS like I should create a new method in my questions_controller called "verify_answer" or something a long those lines.
This breaks REST.
What do you think?
thanks!
AnswersController#create should accept the answers. Whether or not this controller actually has a related Answer model is irrelevant. One action should never perform two actions. For instance, if your QuestionsController#show both displays the question, and accepts a :put or :post with the answer to the question then you are breaking basic rails design principals.
Note that your routes file might very well look like this:
resources :questions do
resource :answer
end
Which will expose the /questions/8/answer route that you can :post to, which will go to AnswersController#create.
Off the top of my head I'm forgetting the exact name of the helper url method you can use to generate the url. Something like question_answer_path(#my_question).
This routing file is for rails3, which I assume is what you're using since there's no reason to use anything else if you're starting a new app in my opinion :p
If you do have an Answer model (maybe you want to store users' answers and look at them later or aggregate them and come up with statistics and such) then you should change the router to use resources :answer instead of the singular version.
For more information about routing and some RESTful tips you should visit the Ruby on Rails guide for routing found here: http://guides.rubyonrails.org/routing.html
I'm on an editing spree! There are times when you might need to add an additional method to your Questions controller that isn't strictly REST. This isn't necessarily considered bad practice but just make sure you look at your decisions and find out if you aren't actually just hiding the existence of another resource. I don't consider this to be one of those times as explained above :)

URL rewriting in ROR

I am Amit. i am new to Rails. Please forgive me if ask any stupid
questions.
I have gone through this article. I am also suffering with the same
problem.
my website URL like this: locahost:3000/users/edit/30
I don't want to show the controller:users and action: edit.
I want to Re-Write (rewrite) the URL or i want to maintain the URL as
http://127.0.0.0:3000/30/ only.(30 is a user id)
I am not interested to show the controller(user) and action (edit)
I total intention is to Hiding (HIDING) and rewriting (REWRING) the URL
and mainly i want to hide the URL Extensions with controller and actions
mainly..
It's an odd requirement to want to use a route this way as it will make it difficult for you to expand this scheme to support other actions in your application. One of the advantages of Rails conventions done as they are is that you usually don't have to worry about (often trivial) application details or have to have strong opinions about them.
But it you really, really want to, you can add this to your config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.connect "/:id", :controller => "users", :action => "edit"
end
Remember that this limited scheme will mean you can only route to the edit action. Not terribly useful I would suggest.
The rails routes.rb file is your answer:
Lots of information here on how to do exactly what you need:
http://guides.rails.info/routing.html#customizing-resourceful-routes
For most application I have been using the standard:
/script.cgi?arg1=foo&arg2=bar
Now obviously /user/edit/eric looks much better for a URL that involves
editing the "Eric" user. But how does this work out when you have
multiple items. For example if I want to delete a group of users. I
might have something like this in the old way:
/user/delete.cgi?id=3&id=5&id=7
or for a more readable format we could have:
/user/delete.cgi?username=eric&username=john&username=paul
This of course assumes that usernames are unique. :) So it seems that I
would want something like:
/user/delete/eric/john/paul
This makes it obvious what is happening from the url. But how do I
generate this? And if a action receives this request how does this get
parsed so I have something like:
#delete_usernames ===>>> [ 'eric', 'john', 'paul' ]
This way I can then load up those users and delete them. I know that
ActionController provides some methods for dealing with URL rewriting
but I am unsure how to best use them. Any help or pointers are greatly
appreciated.

Non-CRUD Controller Actions

This might seem like a n00b question, but I am trying to break some of my bad practice that I may have adopted using MVC, so I hope you can help me out
So, imagine I want to do something like "Upload CSV And Parse It", it doesn't seem obvious to me to fit it into the CRUD pattern... I am not interacting with the DB, so i don't need add or update or delete, but I still want to be able to use the action in a meaningful way from different views. Thus, it is "ok" to just an action called "UploadCSV" and have it be accessible via a URL such as "/data/uploadcsv"
Your thoughts are much appreciated!
Tom
It sounds like you are talking about RESTful ideas (having actions called index, create, new, edit, update, destroy, show).
In MVC you can call an action largely whatever you want (so yes, you can call it uploadcsv if you want). If you want it fit RESTful principles you might want to think about what the action is doing (for example is a data upload essentially a create or an update function) and name it using one of the RESTful action names.
I believe I have the same point of view as you.
In my projects I try to be as restful as possible whenever I can. However as you said sometimes a special case just does not 'fit'
After all it is also a question of 'feeling'
If you provide a csv import function, I see it as perfectly correct to not create a full REST implementation for CSV.
Let's imagine in your application you have clients. And you wnat to give the option for clients to import data using csv. You can add a route for this action using:
map.resources :clients, :member => { :uploadcsv => :get }
The route is properly declared, Your 'clients' resource is completely restful and you have an additional action properly declared to manage data importation.
The only warning I have is: don't use a route like this one "/data/uploadcsv". From my point of view It lacks clarity. I like to be able to understand what my application is going to do just be looking at the url. And '/data' is too vague for me :)
The persistence of the resource is not crucial here. I suppose that what you are doing here is this - creating some kind of resource (although not persistent) out of the csv provided. The thing here is to think about what this csv file represents. What's inside? Is it something that will become a collection of resources in your system, or is it a representation of only one object in your system? If you think about it it has to be something concrete. Can you be more specific about your problem domain?

Resources