Rails 3 - показывает все ошибки для моделей has-one, принадлежащих моделям через контроллер - PullRequest
1 голос
/ 15 марта 2012

Я разрабатываю приложение RoR, и я встретил то, что не могу решить. У меня есть 2 модели - Пользователь и Учитель .

class User < ActiveRecord::Base
  ...
  has_one :teacher
  accepts_nested_attributes_for :teacher 
end

class Teacher < ActiveRecord::Base
  ...
  belongs_to :user
end

Также у меня есть вид с формами для заполнения данных пользователя и учителя. После отправки данных из этой формы отправляется другим способом моего контроллера - create_teacher . Также у меня есть другой метод new_teacher , в этом методе у меня есть мой взгляд с формами.

class AdminsController < ApplicationController
  def new_teacher
    @user = User.new
    teacher = @user.build_teacher
  end

  def create_teacher
    params[:user][:user_role] = "teacher"
    user = User.new(params[:user])

    if user.valid?
      user.save
      teacher = user.build_teacher( params[:user][:teacher_attributes] )
      if teacher.valid?
        teacher.save
        redirect_to admins_users_of_system_path
        flash[:success] = "Teacher created!"
      else
        redirect_to admins_new_teacher_path
        flash[:error] = teacher.errors.full_messages.to_sentence
        user.destroy
      end
    else
      redirect_to admins_new_teacher_path
      flash[:error] = user.errors.full_messages.to_sentence
    end
  end
end

Мой взгляд new_teacher.html.erb

<%= form_for @user, :url => create_teacher_url, :html => {:class => "form-horizontal"} do |f| %>
  <%= field_set_tag do %>
    <%= f.fields_for :teacher do |builder| %>
      <div class="control-group">
        <%= builder.label :teacher_last_name, "Last name", :class => "control-label" %>
        <div class="controls">
          <%= builder.text_field :teacher_last_name %>
        </div>
      </div>

      ...
    <% end %>


    <div class="control-group">
       <%= f.label :user_login, "Login", :class => "control-label" %>
        <div class="controls">
          <%= f.text_field :user_login, :value => "" %>
          <%= link_to_function "Generate login", "generate_login()", :class => "btn" %>
        </div>
    </div>
      ...
  <% end %>

    <%= f.submit "Create", :class => "btn btn-large btn-success" %>
<% end %>

У меня есть 2 вопроса:

1) Как я могу показать все ошибки (для пользователя и учителя)? Это возможно?

2) Возможно ли сохранить мои данные в формах, когда я перенаправлю на admins_new_teacher_path из create_teacher метод?

Ответы [ 4 ]

2 голосов
/ 15 марта 2012

на странице просмотра вы можете использовать form.object.errors Проверьте код

Для объекта формы f используйте f.object.errors в боковой форме. для конструктора объектов формы builder.object.errors в сторону вложенной формы

И сделать render :action => :new_teacher на контроллере

Чтобы получить объект, вы можете написать <%=debug(form.object.errors)%> как ссылку

0 голосов
/ 20 марта 2012

Я нашел правильное решение. Для этого мы должны использовать accepts_nested_attributes_for. Затем, когда мы сделали это, когда мы создаем для моделей

user = User.new( params[:user] ) # Using nested attributes in our model
if user.save
   ..
else
   all_errors = user.errors 
end

Здесь мы получаем все ошибки user.errors.

0 голосов
/ 15 марта 2012

Вы могли бы е. г. подтвердите свое поле teacher_last_name в вашей модели:

validate :ensure_teacher_exists

def ensure_teacher_exists
  unless Teacher.find_by_teacher_last_name(teacher_last_name)
    errors.add(:teacher_last_name, "does not exist")
  end
end

Тогда вы должны добавить в свой взгляд:

<%= builder.error_message_on :teacher_last_name %>

Это отобразит сообщение об ошибке рядом с полем.

Если вы столкнулись с ошибкой «неопределенный метод», добавьте следующий метод в config / initializers / form_builder.rb

def error_message_on(attr)
  message = Error.message(object, attr)
  @template.content_tag(:div, message, :class => 'error_message') if message.present?
end
0 голосов
/ 15 марта 2012
def create_teacher
  user_errors, teacher_errors, redirect_path = nil, nil, nil 

  params[:user][:user_role] = "teacher"
  user = User.new(params[:user])

  if user.save
    redirect_path = admins_users_of_system_path
    flash[:success] = "Teacher created!"
  else
    redirect_path = admins_new_teacher_path
    user_errors = user.errors.full_messages.to_sentence
    teacher_errors = user.teacher.errors.full_messages.to_sentence if user.teacher
  end

  errors_arr = [user_errors, teacher_errors].compact
  flash[:error] = "Errors for user: \n" + errors_arr.join("\n Errors for teacher") if errors_arr.present? 
  redirect_to redirect_path
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...