Route perform wrong action on submit form_with [closed] - ruby-on-rails

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 20 days ago.
Improve this question
i'm having trouble with my rails aplication.
i have a form who should submit some fields to be search to /cities/search/<params_here>.
but, when i submit form, the routing goes to wrong action, and perform a set_city funcion... (??? why this happens ??? )
if the route exists and be declared before the other routes generates from :resources, that should't work?

It seems that there are two problems with the above code.
1.The URL in the form_with:
The URL ideally should be url: "cities/search",.
Since you are using form_with, the values will be available in the form of query params.
This is where our 2nd change comes in.
2.The route that you've set:
It should be get '/cities/search', to: 'cities#search', and as mentioned above, the form fields and their values will be available in the query params.
In the cities_controller's search action, you'd get the params by using params[:query] and params[:search].
Please check form helpers once so that you get a clear idea of it's working.
I have not tested this, so let me know if this helps and if there are any other issues after the above changes.
Also, it is good practice to post the code in the questions in text format rather than images. Ref. this link to understand why.

You can use a collection route without needing to think about route priority:
resources :cities do
get 'search', on: :collection
end

Related

How rails component interact with each other in background? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
For example: How objects are called from controller on view?
Which methods, techniques are running in background?
Please help.
Thanks in advance.
you should check these out
http://railscasts.com/episodes/397-action-view-walkthrough
http://railscasts.com/episodes/395-action-controller-walkthrough
http://railscasts.com/episodes/319-rails-middleware-walkthrough
These screencasts will show you what happens in the background.
This question is like how components in airplane interact with each other so plane flies?
Anyway, when you call any action at any url, Rails will try to match it with routes.
get 'posts', to: "posts#index"
will match /posts routes and will look through your controllers and start PostsController.action(:index).
After that, while executing index action of your controller it will initialize instance variable #posts which is usually Post.all.
And the last thing, PostsController will call renderer, passing action, all instance variables, sessions and url-params. ActionView Renderer will initialize the instance of view with proper template app/views/posts/index.html.erb, put variables there and send page to user.

RESTful API best practices, update vs custom action [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm implementing a RESTfull API to talk to AWS RDS, security_groups resource supports the typical CRUD verbs. When it comes to "authorize" and "revoke" i'm not sure what's the best practice, which one do you think is best?
Custom action, params in url
PUT agifog:3000/rds/security_groups/:security_group/authorize?ec2name='default'&ec2owner='0123456789'
Custom action, passing params
PUT agifog:3000/rds/security_groups/:security_group/authorize
{
"ec2name": "default"
"ec2owner": "0123456789"
}
Standard update
PUT agifog:3000/rds/security_groups/:security_group
{
"operation": "authorize"
"ec2name": "default"
"ec2owner": "0123456789"
}
PUT does not mean "update" any more than POST means "insert". PUT means "put this here".
RESTful practises revolve around treating your URLs as resources, entities which have some meaning in your domain, which you perform actions against (the verb of the HTTP request).
What you could do is consider the security group to be the resource on which you are acting and PUT users into the group or DELETE them from the group:
PUT agifog:3000/rds/security_groups/:security_group/default
{
"ec2owner": "0123456789"
}
DELETE agifog:3000/rds/security_groups/:security_group/default
These could then correspond to authorize and revoke actions, plus makes it easy to see how a GET on the group could produce a list of all the users currently in the group.
The second seems the most RESTful. You've got a resource (security group) and a custom action (authorize) that will respond to your request's verb (PUT).
PUT agifog:3000/rds/security_groups/:security_group/authorize
{
"ec2name": "default"
"ec2owner": "0123456789"
}
and similarly:
PUT agifog:3000/rds/security_groups/:security_group/revoke
(NOTE: I'd probably prefer a POST for the above if it will be generating a session or some other authentication data/token.)
For comparison, if you were interested in updating the attributes of that resource, you'd want to do something like:
PUT agifog:3000/rds/security_groups/:security_group
{
"some_attr1": "some_val"
"some_other_attr": "some_val"
}
In which case the PUT implies that it is an UPDATE to this resource.

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 :)

Trying to understand the Ruby on Rails API docs [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I'm diving into Ruby on Rails and I'm trying to get a grasp on the available docs for the API. I'm trying to find out what the list of "options" are for the redirect_to method in the ActionView API. In the RoR API docs, it says...
redirect_to(options = {}, response_status = {})
but it doesn't list what the available options are.
What are the available options for the redirect_to method?
Just so I don't have to ask more questions, where can I find this list of options in the API docs?
As the doc says:
Redirects the browser to the target
specified in options. This parameter
can take one of three forms:
Hash,
Record,
String starting with protocol:// (like http://),
String not containing a protocol,
:back.
Example:
redirect_to :action => "your_action_name"
or
redirect_to post_url(#post), :status => :found
UPDATE 1: (after the downvote ;) )
Its not about specific keyworks, its its "types" of data passed in the option. As you said, what about "id" or "action", they are a part of a hash. see 1.
Hash - redirect_to :action => "show", :id => 5
Record - post
String starting with protocol - "http://google.com"
String not containing a protocol - /images/foo.jpg
:back
So, these are the 5 "types" of values which can be passed in redirect_to, it was again a copy from ruby docs because that is what is stands for. I cannot be more clear than that.
UPDATE 2
Let's take an example: Say, you have ordered an item and after you make the payment, you should be redirected back to that item's page which you have just ordered.
Code_for_placing_the_order
redirect_to :action => "show_item", :id => 5, :current_user => "john"
So, when you do this, the action, "show_item" will be called, which takes in id as an lookup value for the item and the current logged in user current_user.
So, as on a form submit, you call an action and pass the form values, you do the same in redirect.
UPDATE 3
The example I gave was of a hash. So, a hash is created which is passed over the URL to the redirected page.
key | value
-------------------------
action | show_item
id | 5
current_user | john
Now, this hash is forwarded to the next page. The values of action and id should be same and then you can add ANY symbol you want to. They will just be forwarded with it's respective value where you can read them in your show_item action method.
PS: I am learning rails, suggestions are welcomed :)

Rails routing: how to mix "GET" and "PUT"

Not sure how to frame this question (I'm still wrapping my head around Rails).
Let's try this:
Say I wanted to implement the user side of Ryan Bates' excellent railscast on nested models. (He shows how to implement a survey where you can add and remove questions and answers dynamically). I want the user's side of this: to be able to answer questions and, not in the tutorial, be able to add comments.
It seems to me that you have to implement a view that shows the questions and answers, allow selection of the answers, and the input of comments. So there would need to be a way to show the information, but also update the model on input, right?
I know I'm not explaining this very well. I hope you understand what I'm getting at.
Is it just a question of setting up the right routes? Or is there some controller mojo that needs to happen?
The typical way to do this in Rails uses "resourceful" routing, which more or less naturally maps the standard CRUD actions to methods in your controller, using the appropriate HTTP verbs.
In the routes file (config/routes.rb), you set up the desired resources and actions. For example:
map.resources :questions, :has_many => :answers
Would set up a routing scheme for a question with multiple answers, mapping to the actions according to Rails' conventions:
index: GET /questions/1/answers # list of answers for question id=1
show: GET /questions/1/answers/2 # display answer 2
new: GET /questions/1/answers/new # render form for new answer for question id=1
create: POST /questions/1/answers # create a new answer for question id=1
edit: GET /questions/1/answers/2/edit # render form for answer for question id=1
update: PUT /questions/1/answers/2 # update answer 2
destroy: DELETE /questions/1/answers/2 # delete answer 2
In the controller you create methods mapping to these standard actions. You can also create your own methods and actions for things that don't fall into the CRUD paradigm (like a search for an AJAXified autocomplete field, for example)
Hope that answers some of your question.
You need a "question" resource, "answer" resource and "comment" resource. You also need to implement:
POST for "answer (which is "create" method in controller) to answer the question
POST for "comment" (which is "create" method in controller) to create comments
PUT for the "question" (which is "update" in controller) to "pick" answers, which is effectively changing the state of the "question" resource
In ASP.NET MVC there are two controller methods with the same name but different parameter signatures. One method is decorated with an attribute that tells it to service GETs, the other is decorated with an attribute that tells it to service POSTs. The GET method displays the view, the POST method updates the model.
I assume that it works in a similar fashion in Rails.

Resources