Accessing rails routes in javascript

后端 未结 8 1608
星月不相逢
星月不相逢 2020-12-08 19:39

Can anyone explain how i can access the rails routes/names routes in javascript ?

The following are some of the things i tried http://github.com/jsierles/js_named_r

相关标签:
8条回答
  • 2020-12-08 20:11

    What I did based on Teemu's great answer:

    In your controller:

    def show
      @section = Section.find(params[:id])
      respond_to do |format|
        format.html
        format.json { render json: @section}
      end
    end
    

    In your view:

     <input type="hidden" id="section_path" data-path="<%= @section.id %>" name="section_path" value="foo">
    

    In your js:

    var id = $('#section_path').attr('data-path');
    
    $.ajax({
        url:'/sections/'+ id +'.json',
        type:"GET",
        success: function (data){
            console.info(data);
        },
        error: function (xhr, status){
            console.info(xhr.error);
        }
    });
    
    0 讨论(0)
  • 2020-12-08 20:17

    If I understand your requirement correctly you want Javascript code in your views to have access to the named routes. If so, then one simple way to do this is to render your Javascript code through a template (ERB, Haml, etc) and then to expand the routes something like the following:

    ERB:

    <script>
    
      $.get('<%= some_named_route_path %>', function(data) {
    
      });
    
    </script>
    

    Haml:

    :javascript
    
      $.get('#{ some_named_route_path }', function(data) {
    
      });
    

    UPDATE: Adding suggestions for public/javascripts/ case

    Accessing named routes from the public folder is a bit trickier but there at least 2 ways that come to mind, neither of which is entirely satisfactory but, one or either of which might suit your application

    1. Create javascript templates in (say) lib/javascripts using ERB named like '*.js.erb' and a rake task to expand those templates into public/javascripts before deploying (say as a step in your Capistrano recipe for example). Downside of that is that your changes are not made available live on the site until the templates are expanded and you might not get the right syntax highlighting of your javascript with an .erb extension file
    2. Create per-view javascript helper functions in a content_for :head block which expand the named routes and make those available to code from your public javascript files. If you're careful with namespacing and conventions this might work out well. The downside is that the code calling these javascript helpers is decoupled from the code that defines them which could be confusing for maintainers or prone to abuse.

    In some view:

    <% content_for :head do %>
      <script>
        SomeNameSpace.helper_to_some_named_route = function() {
          return '%<= some_named_route_path %>
        };
      </script>
    <% end %>
    

    Then in public/application.js (say)

    $.get(SomeNameSpace.helper_to_some_named_route(), function(data) {
    
    });
    
    0 讨论(0)
  • 2020-12-08 20:18

    If you are using a JS pipeline that supports import (ES6 + webpacker), you might want to check out js_from_routes, a code-generation library that works seamlessly with Rails reloader.

    For each endpoint that you'd like to access from JS, it will generate a method that can help you build a URL or make a request.

    resources :video_clips, only: [:update], export: true
    

    By using it in combination with axios, these generated helpers can be convenient and easy to use:

    import VideoClipsRequests from '@requests/VideoClipsRequests'
    
    VideoClipsRequests.update({ data: video })
      .then(onVideoUpdate)
    

    Have in mind that you can adjust the generated code by providing a custom template, so it can adapt to any technology you are using, even plain jQuery.

    Benefits:

    • No need to manually specify the URL, preventing mistakes and saving development time.
    • If an action is renamed or removed, the helper ceases to exist, which causes an error that is easier to detect than a 404.
    0 讨论(0)
  • 2020-12-08 20:19

    See http://tore.darell.no/pages/javascript_routes:

    JavascriptRoutes converts your Rails routes into JavaScript. You can then access (generate) them in the browser (or any other JS environment). It supports both normal and named routes, and creates helper functions for the latter.

    Update: It looks as though someone has forked this if you prefer jQuery: https://github.com/ajnsit/javascript_routes

    0 讨论(0)
  • 2020-12-08 20:26
    1. gem install the "angular_rails_templates"
    2. Create a file called angular_rails_templates.rb in the config/initializers folder
    3. copy following code in the file and restart server. (including "module CustomERBEngine" for it cannot be added to code block by 4 space)

    module CustomERBEngine

    class ERBTemplate < Tilt::ERBTemplate
    
    def evaluate(scope, locals, &block)
      scope.class_eval do
        include Rails.application.routes.url_helpers
        include Rails.application.routes.mounted_helpers
        include ActionView::Helpers
       end
          super
        end
      end
    end
    
    Tilt.register CustomERBEngine::ERBTemplate, '.erb'
    
    0 讨论(0)
  • 2020-12-08 20:33

    bjg really answered this, but I thought I'd extract the relevant part and amplify with an example.

    You simply provide your view a string variable whose value is a named Rails path, and then use that value in the Javascript of your form. An example that illustrates how a controller method can specify the path for another method, to be opened by the script on the press of a button:

    File config/routes.rb:

    ...
    resource :foo, :only => [:show, :reset]
    ...
    match 'foo_reset_path' => 'foo#reset'
    

    Commanding rake routes will now produce, among other output, this:

    foo             GET  /foo(.:format)            foo#show
    foo_reset_path       /foo_reset_path(.:format) foo#reset
    

    foo_reset_path is what we're going to use here, but you can of course use this method with any named Rails path.

    File app/controllers/foo_controller.rb:

    ...
    def show
      @reset_path = "foo_reset_path" # simply the string you'd use in the
                                     # Rails code for opening the path
      ...
    end
    ...
    def reset
      ... # reset some variables to their default values
      redirect_to foo_path # causes the show method to be called, and the HTML
                           # page to be redisplayed
    end
    

    File app/views/foo/show.html.erb:

    ...
    <input type="hidden" id="reset_path" name="reset_path" value="<%= @reset_path %>">
    ...
    <script>
    $(document).ready(function() {
        ...
        /* Hang functionality on the "Reset form" button. */
        $('#reset_button').click(function () {
            var reset_path = $('#reset_path').val();
            window.open(reset_path, "_self")
        });
        ...
    })
    </script>
    

    I'm using JQuery here, but the basic idea should be clear. The script adds a hook to the button element whose id is reset_button, so that clicking on the button causes the reset method of foo_controller to be called.

    0 讨论(0)
提交回复
热议问题