ruby-on-rails – 多模型保存,如何包装事务和报告错误
我有一个注册表单模型,在注册期间接受用户输入:
class RegForm include ActiveModel::Model include ActiveModel::Validations attr_accessor :company_name,:email,:password validates_presence_of # ... end 在此注册过程中,我有多个需要创建的模型,我不确定如何正确显示错误消息以及如何将模型错误消息冒泡回UI. if @reg_form.valid? account = Account.create!(@reg_form) else ... Account.create!好像: def self.create!(reg_form) account = Account.create_from_reg!(reg_form) location = location.create_from_reg!(account,reg_form) .. .. account.location = location .. account.save! account end >所以我很困惑如何显示所有这些节省的模型的错误消息 解决方法
让我们从头开始.
我们希望我们的注册表单对象具有与任何其他ActiveRecord模型相同的API: // view.html <%= form_for(@book) do |f| %> <% end %> # controller.rb def create @book = Book.new(book_params) if @book.save redirect_to @book,notice: 'Book was successfully created.' else render :new end end 为此,我们创建以下对象: class RegForm include ActiveModel::Model attr_accessor :company_name,:password def save # Save Location and Account here end end 现在,通过包含ActiveModel :: Model,我们的RegForm获得了大量功能,包括显示错误和验证属性(是的,不必包含ActiveModel :: Validations).在下一步中,我们添加一些验证: validates :email,:password,presence: true 我们更改保存,以便它运行这些验证: def save validate # Save Location and Account here end 如果所有验证都通过,则validate返回true,否则返回false. validate还向@reg_form添加了errors(所有ActiveRecord模型都有一个错误哈希值,当验证失败时填充该哈希值).这意味着在视图中我们可以执行以下任何操作: @reg_form.errors.messages #=> { email: ["can't be blank"],password: ["can't be blank"] } @reg_form.errors.full_messages #=> ["Email can't be blank","Password can't be blank"] @reg_form.errors[:email] #=> ["can't be blank"] @reg_form.errors.full_messages_for(:email) #=> ["Email can't be blank"] 同时,我们的RegistrationsController看起来应该是这样的: def create @reg_form = RegForm.new(reg_params) if @reg_form.save redirect_to @reg_form,notice: 'Registration was successful' else render :new end end 我们可以清楚地看到,当@ reg_form.save返回false时,将重新呈现新视图. 最后,我们更改保存,以便我们的模型保存调用包含在transaction中: def save if valid? ActiveRecord::Base.transaction do location = Location.create!(location_params) account = location.create_account!(account_params) end true end rescue ActiveRecord::StatementInvalid => e # Handle database exceptions not covered by validations. # e.message and e.cause.message can help you figure out what happened end 值得注意的要点: >创造!用来代替创建.如果引发异常(通常会发生爆炸的方法),则仅回滚transaction. return if invalid? >我们可以通过执行以下操作将数据库异常(like an email uniqueness constraint)转换为错误: rescue ActiveRecord::RecordNotUnique errors.add(:email,:taken) end >我们可以使用符号 errors.add(:base,'Company and Email do not match') (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |