Подтвердить что ты не робот

Ruby on rails: уникальный ресурс и form_for

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

routes.rb:

resource :order

мнения/заказы/new.html.erb:

<%= form_for @order do |f| %>
   ...
<% end %>

Но когда я открываю новую страницу заказа, я получаю сообщение об ошибке:

undefined method `orders_path`

Я знаю, что я могу установить :url => order_path в form_for, но каков истинный способ разрешения этого столкновения?

4b9b3361

Ответ 1

К сожалению, это ошибка. Вам нужно будет установить URL-адрес, как вы упоминаете.

= form_for @order, :url => orders_path do |f|

Ответ 2

Откуда этот магический путь?

Мне потребовалось много трассировки, но в конечном итоге я обнаружил, что url_for определяет путь для вашей модели, используя метод polymorphic_path, определенный в ActionDispatch:: Routing:: PolymorphicRoutes. polymorphic_path в конечном итоге получает автомагический путь для вашей модели, вызывая что-то по строкам:

record.class.model_name.route_key

Я немного упрощаю, но это в основном это. Если у вас есть массив (например, form_for[@order, @item]), то вызывается выше для каждого элемента, и результаты объединяются с _.


Метод model_name в вашем классе происходит от ActiveRecord:: Naming.

module ActiveModel
  ...
  module Naming
    ...
    def model_name
      @_model_name ||= begin
        namespace = self.parents.detect do |n|
          n.respond_to?(:use_relative_model_naming?) && 
                                                 n.use_relative_model_naming?
        end
        ActiveModel::Name.new(self, namespace)
      end
    end
  end
end


Как его изменить?

К счастью ActiveModel:: Name предварительно вычисляет все значения, включая route_key, поэтому для переопределения этого значения все, что нам нужно сделать, это изменить значение переменной экземпляра.

Для ресурса :order в вашем вопросе:

class Order < ActiveRecord::Base
  model_name.instance_variable_set(:@route_key, 'order')
  ...
end

# new.html.erb
<%= form_for @order do |f| # Works with action="/order" %>
    ...
<% end %>

Попробуйте!