Два контроллера, одна модель, почему мое приложение ищет вторую модель?

У меня есть модель Ордена.

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

Администраторы получают полный набор представлений для создания, редактирования, просмотра, удаления и управления заказами при поддержке контроллера покупок.

Насколько я могу судить, контроллер Purchases должен общаться только с моделью Order, но следующее сообщение об ошибке заставляет меня думать, что он ищет несуществующую модель Purchase:

ActiveRecord::StatementInvalid in PurchasesController#new
NameError in PurchasesController#new
uninitialized constant Purchase
Rails.root: /Users/steven/Dropbox/testivate

Это что означает ошибка? Если это так, как мне запретить контроллеру Purchases пытаться найти модель Purchase?

Мой код...

app/controllers/purchases_controller.rb:

class PurchasesController < ApplicationController
  def new
    @purchase = Order.new
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @purchase }
    end
  end
  def create
    @purchase = Order.new(params[:purchase])
    respond_to do |format|
      if @purchase.save
        format.html { redirect_to purchase_path(@purchase), notice: 'Purchase was successfully created.' }
        format.json { render json: @purchase, status: :created, location: @purchase }
      else
        format.html { render action: "new" }
        format.json { render json: @purchase.errors, status: :unprocessable_entity }
      end
    end
  end
end

/config/routes.rb:

Testivate::Application.routes.draw do
  resources :orders
  resources :purchases
end

/app/views/purchases/new.html.haml:

.textbox
  %p#notice= notice
  %h1 New Purchase
  = render 'form'
  = link_to 'List Purchases', purchases_path

/app/views/purchases/_form.html.haml:

= simple_form_for @purchase do |f|
  = f.error_notification
  = f.input :name
  = f.button :submit

Обновление: я только что понял, что "транзакция" является зарезервированным словом в Rails, поэтому я изменил его. Но есть ли что-то еще, что мне нужно исправить?

*Обновление 2: когда я полностью комментирую #new представление и _form, я все еще получаю сообщение об ошибке, поэтому я думаю, что проблема в моем контроллере или маршрутах или где-то еще, кроме использования мной simple_form .*


person steven_noble    schedule 03.12.2012    source источник
comment
Можете ли вы поделиться всеми полями, которые вы используете для модели заказа.   -  person shivashankar    schedule 03.12.2012
comment
Я попробовал ваш код в своем локальном приложении rails, все работает нормально (Under Rails 3.2)   -  person shivashankar    schedule 03.12.2012
comment
t.string :company t.string :url t.string :comp1 t.string :comp2 t.string :comp3 t.integer :user_id t.string :guest_name t.string :guest_email t.string :market_list t.string :industry_list t.string :good_list t.timestamps   -  person steven_noble    schedule 03.12.2012
comment
Я также могу подтвердить, что он отлично работает в тестовом приложении.   -  person Chris Salzberg    schedule 03.12.2012
comment
Есть ли у вас какие-либо фильтры до/после в вашем контроллере приложений?   -  person Chris Salzberg    schedule 03.12.2012
comment
Это полный код контроллера? Используете ли вы, например, CanCan (и его фильтр load_and_authorize_resource)?   -  person Sergio Tulentsev    schedule 03.12.2012
comment
Я удалил свой ответ, так как он был явно неправильным. Я повторю сообщение, если найду лучший ответ, но нам нужно больше информации о потоке контроллера.   -  person Chris Salzberg    schedule 03.12.2012
comment
Shioyama, Получается у вас были обе части ответа. Первая часть заключалась в том, что у меня была declarative_authorization, вызывающая фильтр перед контроллером — фильтр, который делал предположение о модели, которая будет соответствовать контроллеру. После того, как я исправил эту проблему, я столкнулся с проблемой simple_form, которую вы определили, исправив ее с помощью кода, который вы разместили ранее, но затем удалили. Спасибо!   -  person steven_noble    schedule 03.12.2012
comment
@steven_noble отлично! Я восстановил свой ответ ниже и разместил примечание, объясняющее, что это половина ответа, а другая половина находится здесь в комментариях.   -  person Chris Salzberg    schedule 03.12.2012
comment
Потрясающе Рад поставить галочку. Теперь есть новая проблема! См.: stackoverflow.com/questions/13682312/ :-)   -  person steven_noble    schedule 03.12.2012


Ответы (1)


Обновление:

Это половина ответа. Другую половину смотрите в комментариях к вопросу.

Исходный ответ:

Часть проблемы здесь заключается в том, что по умолчанию form_for (который simple_form_for построен поверх) предполагает определенные вещи о том, какие пути использовать для данной записи, которые он выводит из класса этой записи. В вашем случае, поскольку @purchase на самом деле является экземпляром класса Order, эти предположения вам все испортят.

Если вы посмотрите на форму, сгенерированную simple_form_for, вы увидите, что она дает форме как идентификатор, так и класс new_order, и что поля в форме имеют такие имена, как order[name]. Чтобы рельсы использовали purchase вместо order в форме, вы должны передать ей параметр :as.

Из документов для form_for:

Если у вас есть объект, который необходимо представить в виде другого параметра, например Person, который действует как клиент:

И пример, который они приводят:

<%= form_for(@person, :as => :client) do |f| %>
  ...
<% end %>

В вашем случае вы действительно хотели бы сказать, чтобы он рассматривал @purchase как «покупку»:

= simple_form_for @purchase, :as => :purchase do |f|
  = f.error_notification
  = f.input :name
  = f.button :submit

Это позволит правильно получить идентификаторы форм и т. д., чтобы вы могли использовать, например. params[:purchase] в вашем действии создания, как указано выше. Но этого недостаточно, потому что действие (URL) для формы все равно будет /orders. Чтобы изменить это, добавьте параметр :url:

= simple_form_for @purchase, :as => :purchase, :url => purchases_path(@purchase) do |f|
  = f.error_notification
  = f.input :name
  = f.button :submit

Это также решит другой вопрос ты написал.

person Chris Salzberg    schedule 03.12.2012
comment
Спасибо, но на самом деле я получаю ту же ошибку с простым simple_form_for @order, поэтому я не уверен, что это оно...? - person steven_noble; 03.12.2012
comment
Ах, на самом деле я подозреваю, что проблема здесь: render 'form'. Вы передаете @purchase неявно, но это может включать предположения об именах классов. - person Chris Salzberg; 03.12.2012
comment
p.s. какую версию рельсов вы используете? - person Chris Salzberg; 03.12.2012
comment
Привет Сиояма. Я использую Rails 3.2.8. Я не уверен, что понимаю другой вопрос. Форма подхватывает @покупка из покупки#новая. Вот как я делаю все свои взгляды, за исключением того, что все другие представления работают. - person steven_noble; 03.12.2012
comment
@steven_noble неважно, я сегодня не сплю. Это не проблема. Фактически, я воссоздал вашу ситуацию в простом приложении и не получил ошибок: даже с одной моделью представление new отображается нормально. Я не пошел дальше этого, потому что вы говорите, что получаете эту ошибку просто при просмотре страницы покупки new. Возможно ли, что здесь замешано что-то еще? - person Chris Salzberg; 03.12.2012
comment
@steven_noble Обновил мой ответ. - person Chris Salzberg; 03.12.2012