Rails: передать параметры с помощью render :action?

У меня есть форма, которая отображается по-разному в зависимости от параметра, с которым она была вызвана.

Ex.

testsite.local/users/new?type=client

Таким образом, если бы type было a или b, форма отображала бы разные поля.

Моя проблема заключается в том, что форма заполняется неправильно, потому что, если пользователь не может быть правильно сохранен, он отображает форму с сообщениями об ошибках по умолчанию, но также без моего параметра.

testsite.local/users/new

Как я могу вызвать свое действие render и передать ему все, что установлено для этого параметра? Чтобы я мог по-прежнему сохранять свои встроенные сообщения об ошибках о том, почему форма не может быть правильно подсчитана, И должна ли она быть правильной формой?

Вот мое create действие:

def create
   @user = User.new(params[:user])
   roles = params[:user][:assigned_roles]
   if @user.save
     update_user_roles(@user,roles)
     if current_user.is_admin_or_root?
       flash[:message] = "User \"#{@user.username}\" created."
       redirect_to users_path
     else
       flash[:message] = "Congrats! You're now registered!"
       redirect_to app_path
     end
   else
     render :action => 'new'
   end
 end

person neezer    schedule 10.10.2009    source источник


Ответы (4)


Как объяснил другой пользователь, отвечая на мой другой вопрос, связанный с , вот что я был после:

form_for @user, :url => { :action => :create, :type => @type }

... который сохраняет параметр :type для каждого нового действия рендеринга (при условии, что он правильно определен в моем контроллере).

person neezer    schedule 12.10.2009
comment
Что вы делаете, когда хотите определить одно и то же для действий create и update? - person Victor; 06.10.2012

Есть два способа сделать это.

Либо добавьте скрытое поле, либо дополнительный параметр в form_for

Добавление скрытого поля в вашу форму, содержащее именованный тип, и установка его равным params [: type], это сохранит тип при рендеринге, если проверка не пройдена.

Посмотреть код:

<% form_for @user do |f| %>
...
<%= hidden_field_tag :type, params[:type] %>
<%end%>

Добавление дополнительного параметра в форму:

<% form_for @user, create_user_path(@user, :type => params[:type]) %>
...
<%end%>

Любой из них будет делать то, что вы хотите.

person EmFi    schedule 11.10.2009
comment
Как бы вы различали форму между обновлением и созданием? - person Sean; 10.01.2013

Извлечение для руководств Rails

Использование render с :action — частый источник путаницы для новичков в Rails. Указанное действие используется для определения того, какое представление отображать, но Rails не запускает какой-либо код для этого действия в контроллере.

Я полагаю, что ваш new?type=client используется для установки какой-то переменной в вашем новом действии? И эта переменная позже используется в вашем представлении new.html.erb?

Затем вам нужно немного изменить действие создания следующим образом:

  else
     # add code here to setup any variable for type = client
     # and which will be used in your view
     render :action => 'new'
  end
 end
person Aurélien Bottazini    schedule 10.10.2009
comment
Что ж, это по-прежнему нарушает визуальную согласованность моего URL-пути, так что при неудачной отправке формы URL-адрес меняется с new?type=client на просто new. Нет ли способа установить параметр URL для вновь отображаемого действия? Или я все еще что-то упускаю здесь? - person neezer; 11.10.2009
comment
вау, это вызвало у меня столько разочарования. почему он просто не перезагружает новое действие? Мне приходится копировать/вставлять код, который не оптимален. - person Danny; 23.07.2012

Вы всегда можете заставить его:

params[:type] ||= "client"

в вашем новом действии в вашем контроллере. Если тип не установлен, по умолчанию будет клиент. Однако URL этого не покажет.

person Ryan Bigg    schedule 10.10.2009