Какова цель действия нового контроллера в Rails? - PullRequest
2 голосов
/ 09 марта 2011

Скаффолд генерирует новое действие следующим образом:

  def new
    @product = Product.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @product }
    end
  end

 def create
    @product = Product.new(params[:product])

    respond_to do |format|
      if @product.save
        format.html { redirect_to(@product, :notice => 'Product was successfully created.') }
        format.xml  { render :xml => @product, :status => :created, :location => @product }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @product.errors, :status => :unprocessable_entity }
      end
    end
  end

, и представление визуализирует часть с именем form.Поскольку форма new отображается с действием, установленным для создания нового продукта, какова цель @product?Я вижу, что действие create также создает новый объект.Используется ли он только для того, чтобы вы могли связать форму с объектом, чтобы все правильно переходило от действия к действию?

Ответы [ 3 ]

4 голосов
/ 09 марта 2011

Вы можете думать о @product в новом действии как о несохраненном объекте, который просто заполняет поля формы, отображаемые в представлении.Это делает new.html.erb почти таким же, как edit.html.erb, и позволяет им совместно использовать один частичный _form.html.erb.

Когда этот частичный элемент используется в новом действии, поля заполняются свежим, пустым и несохраненным объектом @product.Это Product.new, который появляется в новом действии.Когда частичное используется в действии редактирования, у вас есть объект @product, который предположительно имеет значения для всех его атрибутов.Теперь предположим, что вы не использовали @product в новом действии.Форма, используемая в new.html.erb, должна отличаться от формы, используемой при редактировании.Удачи в их сохранении, если вы когда-нибудь добавите новое поле в модель.

Другое преимущество этого подхода заключается в том, что вы можете предварительно заполнить атрибуты нового @product до того, как они будут отображены в представлении.Предположим, вы хотите использовать имя «новый продукт» в качестве имени по умолчанию для каждого продукта.Вы можете сделать это в новом действии следующим образом:

def new
    @product = Product.new(:name => 'new product')

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @product }
    end
  end
3 голосов
/ 09 марта 2011

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

Контроллер передает объект @product (новый или существующий), и Rails видит, является ли это новой записью или существующей записью. На основании этого он принимает определенные решения, такие как извлечение значений записи в поля ввода (существующие) и действие контроллера для отправки формы при отправке.

1 голос
/ 09 марта 2011

Если у вас есть form_for, новое действие используется для правильной инициализации @product в form_for @product, что предполагает модель ActiveRecord. Если я правильно помню, область действия Product (для любого действия контроллера) заканчивается запросом, поэтому действие create не знает о новом действии, что требует инициализации другого Product.

Метод form_for использует переменную @product, чтобы правильно назначить форму контроллеру ресурсов, чтобы найти правильный URL-адрес, идентификатор (в случае обновления) и многое другое. Вы можете прочитать об этом в разделе 2.3 http://guides.rubyonrails.org/form_helpers.html

Если вас беспокоит использование памяти, вам не нужно инициализировать @product, но тогда вам придется вручную создать свою собственную форму, не используя симпатичный form_for.

на основе ресурсов.
...