How Does Rails 3's "data-method='delete'" Degrade Gracefully? - ruby-on-rails

Rails 3 does some cool stuff to make Javascript unobtrusive, so they've done things like this:
= link_to "Logout", user_session_path, :method => :delete
..converts to
Logout
But it just occurred to me.. When I turn off javascript the method isn't DELETE anymore, it's GET as expected. So are there plans to, or is there some way to, allow these data- attributes to degrade gracefully, so that link still is a DELETE request?

The change they made in Rails 3 with these data- attributes wasn't about graceful degradation, it was about unobtrusive JavaScript.
In Rails 2, specifying :method => :delete on a link would generate a whole bunch of inline JavaScript that would create a form with a hidden input and then submit the form. That was the same as it is now: turn off JavaScript and it defaults to a GET request. As such, supporting the case of no JavaScript is the same as it was before.
One option is to use a form/button instead of a link so you can include the method as a hidden field, much like the Rails 2 JavaScript does. Another option is to have the GET version take you to an intermediate page which in turn has the form/button.
The benefit of the new approach is that it's unobtrusive. The JavaScript for changing the HTTP verb exists in an external file and uses the data- attributes to determine which elements it should be attached to.

Rather than using the link_to method -- which would require you use JavaScript to ensure that the HTTP method is DELETE -- use the button_to method, which will create a form with a hidden input element which tells Rails to treat the HTTP method as DELETE rather than POST. If necessary, you can then use CSS to style the button in the form so that it looks like a link.

The only chance you have is define a form. A link can't be a POST with _method="delete" without Javascript or by form.

It is not possible without javascript.
I make a small jQuery plugin for converting data-method link attribute to pseudo hidden forms (used in laravel project for example).
If you want to use it : https://github.com/Ifnot/RestfulizerJs

Related

Use data-disabled-with on a non form submit button

Rails provides data-disabled-with for button tags on form submits. Super awesome. However, link tags don't get this desired behavior. They're great to prevent users from clicking a button too many times and producing an unwarranted effect.
Is there a way I can do something like:
Purchase me
Rails provides this functionality via the :disable_with parameter of the link_to helper. See docs.
For example:
link_to("Create", create_post_path(#post), remote: true, disable_with: "Creating...")
Recognizing of course that creating a resource via a GET request isn't idiomatic Rails/REST... but this hopefully illustrates how it could be used.

How can I get values from form in controller in rails without using form_helper?

How can I get values from form in controller in rails without using form_helper? By using simple html form, and simple input text-boxes, select-boxes, radio-boxes, etc?
Use a form tag then:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-form_tag
Inside form_tag You can use other helpers like button_tag, field_tag etc, or You can simply write an html code.
The reason why You need to use form_tag or form_for is because of the CSFR security.
If You inspect a form generated by those helpers You will find a hidden field where Rails puts an authenticity token. When user submits a form Rails uses this tag to verify if the form submitted is coming from the current app and not some external call.

Call a Ruby on Rails helper method from a JavaScript js.erb file

Is it possible to call a ruby helper method from within a js.erb file?
I have a helper in application_helper.rb called solve which makes a API call to a third party service, and they only have a ruby client.
The js.erb file isn't being run on the client side, it is being called from within a controller method and run server side as it is PhantomJS.
I call the JS file from the controller
Phantomjs.run('phantom.js.erb', url)
Then within the PhantomJS js.erb file I have tried
var response = '<%= solve(variable) %>'
which just sets the variable as the string <%= solve(variable) %>
I have also tried
var response = <%= solve(variable) %>
but that just seems to make the application hang and become unresponsive.
I have seen other questions similar to this. In those questions they are asking if it is possible to call it from client side JS which I know you need to use an ajax request to do so.
Is this possible?
Try this:
var content = '#{solve()}'
Need a bit more context for this question, but I'll try my best to answer:
Essentially, you wouldn't be able to access your application_helper methods outside of any .erb files. (ie. if you have application.js or any other js file in your pipeline and you are trying to <%= solve %> from there it wouldn't work - mainly because it isn't an .erb file)
There are a lot of ways and architecture to go about solving this, but here are two simple ones:
If you put the JS you want to evaluate inline on the same page as your partial/html.erb page by using <script> //JS ERB CODE GOES HERE </script> It will actually evaluate properly since it is inside of an erb file. However, this is generally looked upon as unclean...
What you probably want to do is pass the value (presumably) you want that comes from the "solve" application_helper in a 'data' attribute on the html element that it affects. By utilizing "unobtrusive javascript" in this way, you simply pass the value through markup and then in your JS you can get the variable by using jQuery code like this. Here's an example:
<%= link_to "test_link", root_path, :data => {:solve => solve } %>
Of course it doesn't have to be a link, any HTML element will do, and then in your jQuery:
$("#test_link").data("solve");
will return to you whatever output comes out of your "solve" method in the application_helper.
it can possible but there are different ways to do it. one way is define the method in helper_method in your controller and call it from your view. and another way is use the gon gem to access some controller value in your javascript. please check what is best for you please check the below links for more help
http://apidock.com/rails/ActionController/Helpers/ClassMethods/helper_method
https://github.com/gazay/gon
http://railscasts.com/episodes/324-passing-data-to-javascript

How to create one form with many possible actions in Rails?

I want to create one form with 2 buttons in rails. Both forms operate on the same data in different ways, and I would prefer to keep the associated functionality in two different methods. Previously I've redirected to the appropriate method after doing a string comparision on params[:commit], but my gut says there's a better approach. Suggestions?
Two different submit buttons that send the form to two different actions:
<%= submit_tag('Insert', :onclick=>"document.myForm.action = 'insert';") %>
<%= submit_tag('Update', :onclick=>"document.myForm.action = 'update';") %>
Instead of "myForm" you need to put whatever is in the "name" property of your tag.
You can set that property in your default form:for tag like this:
<%= form_for(#something, :html => {:name => "myForm"}) do |f| %>
Without using JavaScript, your only solution is what you mention: checking which button was clicked by looking at the POST data in the controller. This is simply due to the nature of the HTML form element. It cannot have more than one value for its action attribute.
If you're not worried about what will happen when JavaScript isn't available, then you can write some script to change the action attribute when one of the submit buttons is clicked, prior to actually submitting the form. In the case of an ajax request, it could simply submit to the correct URL directly without altering attributes on the form.
I also used the params[:commit] method on a form already. Using the I18n helpers makes this a bit less fragile as you can use the same lookup in the view and controller, so you don't encounter the problem that the string changes a bit.
Besides that I can only think of using JavaScript to handle the clicks on the buttons and then send the form data to different Rails actions (Maybe you can change the HTML action attribute of the form with JavaScript before you submit the form).
If you're using prototype.js, you can use Form.serialize() to grab your data from your form and from there use the different buttons to post to different actions.

(Rails) Using "link_to_remote" in conjunction with a popup/popout window...?

What is the most straightforward mechanism by which to "link_to_remote" and popout a window with the data? I need "link_to_remote" because I need to pass certain data along with the url without redoing my routes. If this would be better served by a "link_to" without the need to redo my routes, I'm all for it. I simply can't get it to work, atm.
Thoughts?
Perhaps you're looking for something like:
<%= link_to_function "Show Article in Popout window",
"window.open(#{article_path(article).to_json}, 'show_article')" %>
link_to_remote is used to do XHR requests, so you cannot use it to open a popup window with the response.
You don't need to redo your route anyway, because I assume that if you want to use link_to* to get some data, then you have your controller/action pair defined and accessible already.
Also, usually, Rails applications have the catch all route enabled to match :controller/:action. If that's your case, then you can use link_to that controller/action to get the data.
What window do u mean ? modal window ? if u want to show some data through modal window, then i suggest u to use http://prototype-window.xilinus.com/index.html, it easier to use, just write some js function and create link_to_function in rails helper/view to call the js function.

Resources