can i use ruby on rails get and post for the same method? - ruby-on-rails

I'm new to web development in general and ruby on rails in specific. I'm working on developing a web interface where i'm using a 'Get' and 'Post' requests on the same method. When i use a get method and send parameters (like username and password), they are being visible in the url. Hence, below is what i did.
form1.html.erb
<%= form_for :modify, :method => "post", :url => {:action => "method2"} do |f|%>
#code here to input username and password
<%=end%>
in my routes.rb i wrote the following routes to the method2:
post 'controller/method2'
get 'controller/method2'
When i enter username and password and click on submit, it is finding the post 'method2' and executing the code in the controller, and displaying method2.html.erb as there is a get request for the same method and also there is a view for method2.
However, i suspect this is not the right way to do it. I do not want the password to be visible. I came to know that i have two options, store the password in a session or send a post request. I do not want to store in session as it is not safe. When i write a post method the page expires when the user tries to come back. To prevent either of these happening, i used the same action in controller as post and get and now i do not see any parameters visible in the url.
Please let me know if this is not the right way to do

If you want a solid method for manipulating user & password, I recommend you go through the Ruby on Rails tutorial, it's an excellent tutorial and it will learn you the basics to start with Rails programming, including a safe username/password use.
Alternatively, you can use Devise, which is a very popular gem for this purpose.
I would not try to implement a secure user/password system without really knowing what you are doing...

In your controller you should have this :
render 'controller/method2'
And you should have a file in this path :
app/views/controller/method2.html.erb
You don't need to have two routes.

Related

Set params hash value using link_to without affecting url in Rails 4

When I submit a form, a number of parameters are set without showing up in the url.
I would like to do the same thing with link_to:
<%= link_to((purchase.paid ? 'yes' : 'no'), {action: :index, hidden_id: purchase.id}) %>
produces the url 'http://localhost:3000/purchases?hidden_id=1'. I would like to link to the url 'http://localhost:3000/purchases' while still setting params[:hidden_id] so I can access it in the controller, as if I had submitted a form.
My routes.rb file is as follows:
root to: 'products#index'
resources :products
resources :purchases
match ':controller/(:action/(:id))', controller: :shop, via: [:get,:post]
In answering this, is there anything I should know here about the difference in the way these two things are handled? Is it something about get vs post requests or is there some other principle involved which I'm not grasping?
Yes, it's to do with Get vs Post requests.
A Get request can only send parameters in the URL itself. A post request can also be sent to a URL that includes parameters in the URL itself, but it can also send parameters 'under the hood' so to speak.
So if your routes were set up to allow it, you could send either a get or a post request to http://localhost:3000/purchases?hidden_id=1, but only the post request could include additional parameters under the hood.
Anything else you should know about the difference in the way these two are handled? Yes. In most web frameworks, when you see the parameters server-side, they will be split up into GET params and POST params. Rails doesn't make this distinction, and puts them both in the same params hash. (I think this is silly, but whatever).
Also, a get request can be sent simply by entering the URL in your browser and hitting enter. A post request will generally only be executed by a user submitting a form on a web page. For this reason, get requests are not meant to change any content in your database. They should be for viewing information only. So, eg, if you have a button to delete a resource (eg. a blog post or something) it should be submitted via post. (more info on that at Why shouldn't data be modified on an HTTP GET request?)
Lastly, Rails provides an option in it's link_to helper to allow you to easily make the 'link' use a post request. See the method option at http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to. This basically uses javascript to prevent the normal action of clicking the link (which would be a get request), and submit a post request instead.

Utilizing A Devise Session Through Flex With Rails3-AMF

I have a Flex front end and a Rails 3 back-end that I would like to establish a session to. Before you can access the page embedded with the flex front-end, you are prompted with a html login page through Devise.
I am able to login fine through the html page but cannot get access to the session with Flex using amf requests.
I have the rails session token in flex but cannot pass them into rails correctly. I am attempting to pass the sessiontokin in through a "send" service call like
somethingService.new.send(session_id: '###', _csrf_token: '###' )
and rails is receiving the session param in a hash as like
{0=>{"session_id"=>'###')}}
instead of like
{"session_id"=>'###')}.
Any suggestions on how to fix this issue or to utilize a session with Flex/RubyAmf/Rails are welcomed.
Thx.
It's been a while since I've done anything with integrating flex & rails, but I have a vague memory that the params come through as {0 => params} if not explicitly mapped in the configuration. The rails3-amf readme on github uses this example:
config.rails3amf.map_params :controller => 'UserController', :action => 'getUser', :params => [:session_id]
If your not already, perhaps explicitly defining the session_id in the :params would make the difference?

How do controller actions know which REST operation to perform?

When I'm at /profile/new, for example, and I submit a form to create a profile, Rails knows to perform a POST operation; and when I update that profile from /profile/edit/1, Rails knows to perform a PUT operation... My question is, how does it know to do that?
I can't understand how this works past the controller. What exactly is going on in the background? I've dug around a little bit and I know ActiveRecord and ActiveResource? are involved, but I'd like to know the details. I've only been around since Rails 2.2 and every resource I find seems to teach by example. I'm interested in understanding how things work at a lower level, but there's nothing to guide me through learning by reading apis & source code.
You know how a view page of new page or edit page in a user's scaffold looks right?
form_for(#user) # something like that
So this is a helper method which you can find inside action_view/helper .. file
Basically the form rendering for new and edit will be decided by this form_for method, what this form_for method will do is (I just made some bullet points)
1) It will check what type of input you gave in your form_for
(check api for different ways of using form_for helper)
2) It will decide the the html options based on the below code
if object.respond_to?(:new_record?) && object.new_record?
{ :class => dom_class(object, :new), :id => dom_id(object), :method => :post } # for new
else
{ :class => dom_class(object, :edit), :id => dom_id(object, :edit), :method => :put } # for edit
end
3) It will do one more thing for edit page it will add a hidden field which will have user's id value in it.
Please let me know if you need some more details. I will update my answer accordingly.
The best I can tell, it relies completely on what action you're performing in the controller. For instance, #object.new would be a POST action, where-as #object.find([:params]) would be a GET action, based upon RESTful practice.
I could be off-base, as I'm in the same boat as you but that's my interpretation of it.

Form submission and hyperlinks using GET and POST

I have a search resource, the user can perform searches by filling out a form and submitting it, the create action is called, the Search is saved, the show action is called, and the results are displayed. This all happens with the default POST, and all works fine.
The user may want to save his search in the saved_search table (i don't use the Search table for this purpose as this table stores all searches for the purpose of compiling statistics, and gets cleared on a regular basis). Once the Search is saved, it can be re-run by clicking a hyperlink, this is where i start to get problems.
I see no way of getting my hyperlink to run the create action of Search, with a POST request, and the necessary data.
I then decided to try to get both form submission and the hyperlink to perform a search using a GET request, i was unable to get form_for to run my Search create action using a GET request, it always seems to get routed to my index action.
Can someone suggest a good restful solution to this problem please.
Many thanks
I'm not quite sure what you're trying to do here. If you want to have a form submit with a GET request, you can override the HTML attribute on the form_for helper:
<% form_for blarg, :html => { :method => 'get' } %>
blabla
<% end %>
Rails also supports a way of "faking" the HTTP method by using a "magic" parameter (called "_method"), which makes Rails behave as if it had seen the HTTP method in that parameter.
If you send the form as "get", you must make sure that none such parameter is set. If you wanted to let a hyperlink send a "POST", tweaking this would be the way (a browser will not send a real POST on a click on a link)
Jon,
If I understood right, if the search is already saved, you could just make a get on the resource of the saved search like you did the first time and use the show action to display the result.
Anyway, if you still wants to do a post with a link, the helper method link_to does it for you. Check it out:
http://www.51773.com/tools/api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#M001597
With a :method => :post option it will create a hidden form and post your data.
Hope it helps.

Is there any harm in using a typical GET action for a PUT? (RESTfully speaking)

I have an action that doesn't require a form. So it really only needs the one 'edit' method instead of the RESTful 'edit' --> 'update'. Is there any reason not to do this or a better way?
def edit
#Do a POST(PUT)
end
The harm is that a user could easily navigate to that url and perform a potentially destructive action.
/noform/edit #URL typed by user => Action Performed
/noform/update #URL typed by user => Error is thrown, No Action Performed
A normal browsing experience generates GET requests to the server. The assumption is, any page you can easily navigate to (or type into your address bar) will not perform any data changing functions.
A POST request, generated via a form submission or a AJAX request expects the result that data is changed on the server.
Similarly the two rails "faked" versions of PUT and DELETE also are not actions you could simply navigate to using a browser.
The solution
The solution is to have only the update action and where you originally would have linked to edit use something like the following:
button_to "Add new tracker", noform_path, :method => :put
If there is any type of error, you may still need an edit path to show the user so they can correct something. But from what you have described, a single update action should do the trick.
Gets should always be idempotent -- that is they should not perform any action that will alter the state of the application, database, etc.
Just as an aside -- in true RESTful form an edit would be performed by an HTTP Update action, but Rails simulates this with a post and a hidden value on the form, since browsers don't have HTTP Updates.
It's still not clear to me why you need an update without an input field. Perhaps a little more detail would be helpful.

Resources