Как я могу передать сообщения об ошибках валидации в метод в другом контроллере? - PullRequest
7 голосов
/ 01 апреля 2011

Я только запускаю приложение rails 3, которое имеет родительскую модель и дочернюю модель (parent has_many: children).

Я пытаюсь настроить все так, чтобы после создания нового родителя пользователь перешел к действию show этого родителя (/ parent / id). В этом представлении я включил частичные элементы, чтобы показать всех потомков, и форму для создания нового потомка. После создания нового дочернего элемента пользователь перенаправляется на действие show для родительского элемента, где появится новый дочерний элемент. Это все работает как задумано.

Однако, если я попытаюсь проверить поля в новой дочерней форме, все возникающие сообщения об ошибках не появятся в форме (необходимые строки в представлении есть и являются правильными - вырезаны и вставлены из сгенерированного кода скаффолда). Есть ли способ успешно передать эти сообщения об ошибках для ребенка в родительское действие show?

Вот фрагменты соответствующего кода;

От моего родительского контроллера:

def show
  @parent = Parent.find(params[:id])
  @child = @parent.children.new

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

От моего дочернего контроллера:

def create
  @child = Child.new(params[:parent])

  respond_to do |format|
    if @child.save
      format.html { redirect_to(parent_path(params[:child][:parent_id]), :notice => 'Child was successfully created.') }
               #This works as intended
      format.xml  { render :xml => @child, :status => :created, :location => @child }
    else
      format.html { redirect_to parent_path(params[:child][:patient_id]) }
               #This redirects where I want it to go when validation fails but error messages are lost
      format.xml  { render :xml => @child.errors, :status => :unprocessable_entity }
    end
  end
end

Ответы [ 2 ]

11 голосов
/ 02 апреля 2011

Хорошо, я решил это сам. Спасибо за ответ Терв. Он работает отдельно от неправильного URL из-за отсутствия перенаправления.

Это просто вопрос передачи ошибок через хэш сеанса, а затем их добавления в дочернюю модель в родительском контроллере.

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

В моем детском контроллере

def create
  @parent = Parent.find(params[:child][:parent_id])
  @child = @parent.child.build(params[:child])

  respond_to do |format|
    if @child.save
      format.html { redirect_to(parent_path(params[:admission][:parent_id]), :notice => 'Child was successfully created.') }
      format.xml  { render :xml => @child, :status => :created, :location => @child }
    else
      if @child.errors.any?
        session[:child_errors] = @child.errors
      end
      format.html { redirect_to(parent_path(params[:child][:parent_id])) }
      format.xml  { render :xml => @child.errors, :status => :unprocessable_entity }
    end
  end
end

И в моем родительском контроллере

def show
  @parent = Parent.find(params[:id])
  @child = @parent.children.new
  if session[:child_errors]
    session[:child_errors].each {|error, error_message| @child.errors.add error, error_message}
    session.delete :child_errors
  end
  respond_to do |format|
    format.html # show.html.erb
    format.xml  { render :xml => @parent }
  end
end
1 голос
/ 01 апреля 2011

Что если вы просто отобразите страницу показа родителя, если дочерний объект недействителен?

def create
  @child = Child.new(params[:parent])

  respond_to do |format|
    if @child.save
      format.html { redirect_to(parent_path(params[:child][:parent_id]), :notice => 'Child was successfully created.') }
               #This works as intended
      format.xml  { render :xml => @child, :status => :created, :location => @child }
    else
      format.html { render :controller => :parent, :action => :show }
               # Display the parent's show page to display the errors
      format.xml  { render :xml => @child.errors, :status => :unprocessable_entity }
    end
  end
end

Возможно, вы захотите сделать что-то подобное для действия crate, чтобы убедиться, что родитель существует.

@parent = Parent.find(params[:parent][:parent_id])
@child  = @parent.children.build(params[:parent])

Тогда ваши пользователи не смогут создать недопустимого дочернего элемента, и у вас будет родитель, чтобы снова отобразить страницу показа.Вы не должны давать пользователям возможность устанавливать parent_id для себя.

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