Наследование и маршрутизация пользовательского действия из ApplicationController в Rails - PullRequest
0 голосов
/ 22 октября 2010

Я использую Rails 2.3.2, но я уверен, что это относится и к более новым версиям.Я хотел бы определить пользовательское действие в ApplicationController.Однако я не хочу добавлять собственный маршрут к каждому подклассу контроллера, который использует это действие.Есть простой способ сделать это?

Первым делом я хотел просто направить напрямую к ApplicationController, поскольку метод не должен быть переопределен никакими подклассами.Но я не думаю, что Rails позволяет вам перенаправлять на ApplicationController больше.

Кто-то еще предложил что-то вроде этого:

map.connect ":controller/:action", :controller => my_regex, :action => my_regex

Но мне интересно, может ли это конфликтоватьили переопределение других маршрутов?Или есть ли вообще лучший способ?Спасибо!

Ответы [ 4 ]

0 голосов
/ 11 ноября 2010

В итоге я решил считать свой js_form_builder собственным ресурсом, поэтому у меня есть контроллер, который его доставит.Контроллер принимает необязательные параметры resource_name и id.Если предоставлено, я могу создать экземпляр объекта следующим образом:

@object = params[:resource_name].classify.constantize.find(params[:id]) 

Затем я просто отправляю шаблон js.erb, в котором содержатся все мои качества js_form_builder.Если экземпляр @object был создан, то я могу создать form_for @object, затем пройтись по его атрибутам и создать методы на объекте построителя форм javascript, который будет возвращать входные данные для каждого атрибута, используя для этого теги Rails FormBuilder.

Например:

window.FormBuilder = function() {
  var builder = {};

  builder.form = function() {
    var js = "";
    js += '<%= form_for @object do |f| %>';
    <% @object.attributes.each do |name, val| %>  
      var methodName = '<%= name.camelize(:lower) %>';
      <% if val.class == String %>
        builder[methodName] = $('<%= f.text_field name.to_sym  %>');
      <% end %>
      <% if val.class == TrueClass || val.class == FalseClass %>  
        builder[methodName] = $('<%= f.check_box name.to_sym %> <%= f.label name.to_sym %>');
      <% end %>    
    <% end %>
    js += '<% end %>';
    return $(js);
  };  

  builder.newForm = function() {
    var js = "";
    js += '<%= form_for @object.class.new do |f| %>';
    js += '<% end %>';  
  }

  return builder;
}

В настоящее время я не уверен, насколько полезными будут эти входные данные, поскольку я не могу придумать сценарий, в котором я бы не использовал html.erb для них.Но это было весело, заставляя это работать!:)

0 голосов
/ 22 октября 2010

если вы объявляете этот контроллер в качестве ресурса, такого как map.resource, то вам придется использовать действия по умолчанию или создать свои собственные, добавив member или collection к этому ресурсу.

 map.resources :post, :member => {:update_live_boolean => :post }, :collection => {:get_all_live_posts => :get}

В противном случае, если у вас старый формат маршрутизации и вы не используете REST

  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'

Тогда все, что вам нужно сделать для ссылки на пользовательский контроллер, это предоставить :controller' and: action /: id`переменные при необходимости

<%= link_to "New Custom Controller", {:controller => "new_custom_controller", :action => "index"%>
0 голосов
/ 22 октября 2010

Это часть вашего сообщения, которая касается меня:

Я не хочу добавлять собственный маршрут к каждому подклассу контроллера, который использует это действие.

Сообщество рельсов справедливо становится все более и более осторожным, чтобы не переопределять ненужные маршруты.Все чаще можно увидеть такие вещи:

map.resources :comments, :only => [:new, :create]

. В приведенном выше примере генерируются только маршруты new и create.Это лучшая безопасность и более чистая маршрутизация.Хотя я прямо не отвечаю на ваш вопрос о том, как сделать новый маршрут доступным для каждого ресурса, я говорю, что лучшие практики Rails будут препятствовать этому.Добавьте пользовательский маршрут только к ресурсам, которые будут его использовать.

0 голосов
/ 22 октября 2010

Я не думаю, что это случай изменения ApplicationController, а просто «патч-патч» кода в ActionDispatch::Routing для включения новых действий, которые вы хотите.Это кажется довольно сумасшедшей вещью в схеме вещей, поскольку нет стандартного способа дополнить или расширить обычные действия REST.Я надеюсь, что у вас есть веская причина для этого.

Просматривая код, вы видите, где определены действия по умолчанию, и, возможно, сможете представить новое.Rails 3 имеет немного иную структуру, но идея та же:

    class ActionDispatch::Routing::Mapper::Resources::Resource
      ENHANCED_DEFAULT_ACTIONS = DEFAULT_ACTIONS + [ :myaction ]

      def self.default_actions
        ENHANCED_DEFAULT_ACTIONS
      end
    end

Вам придется изменить ActionDispatch::Routing::Mapper::Resources#resources, чтобы вести себя по-разному, но вы не указали, говорите ли вы одействие коллекции, нового или членского типа, поэтому вам нужно будет просто скопировать и изменить подпрограмму, чтобы она велась так, как вам хочется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...