使用嵌套表单创建用户时Rails回滚

我在尝试将用户添加到我的数据库时收到回滚,但我不确定原因。

我有三个型号: company.rb

class Company < ActiveRecord::Base acts_as_paranoid has_many :locations, dependent: :destroy has_many :users, dependent: :destroy has_many :tests, through: :locations has_many :reports, dependent: :destroy accepts_nested_attributes_for :locations, :users validates_presence_of :name end 

** user.rb **

 class User < ActiveRecord::Base acts_as_paranoid devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable, :registerable belongs_to :company has_and_belongs_to_many :roles end 

** location.rb **

 class Location  { self.identifier.blank? } def generate_identifier self.identifier = SecureRandom.uuid.delete("-") end 

因此,当用户想要注册时,他们需要输入公司,位置和用户信息,这些信息由我的company_controller.rb控制。

** company_controller.rb **

 class CompanyController < ApplicationController def new @company = Company.new 1.times { @company.locations.build } 1.times { @company.users.build } end def create @company = Company.new(company_params) if @company.save redirect_to root_url else render :new end end private def company_params params.require(:company).permit(:name, locations_attributes: [:name], users_attributes: [:first_name, :last_name, :full_name, :email, :password, :password_confirmation]) end end 

表单使用带有嵌套属性的标准form_for ,这样当用户单击提交按钮时,我可以一次性完成所有内容

** company / new.html.erb **

  url_for( :controller => 'company', :action => 'new' ) do |f| %> 

但是,我正在日志中回滚,这是没有发生的,也无法弄清楚原因。

 Started POST "/signup" for 127.0.0.1 at 2015-08-07 13:49:22 -0400 Processing by CompanyController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"2OHwJ9UfEbfkZHjLdm9BfOd7jlRdvoEz0L4NRJCKl64=", "company"=>{"name"=>"ACME Brick", "locations_attributes"=>{"0"=>{"name"=>"Main House"}}, "users_attributes"=>{"0"=>{"first_name"=>"Testin", "last_name"=>"User", "full_name"=>"Test User", "email"=>"test@test.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}}, "commit"=>"Submit"} User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = 7 ORDER BY "users"."id" ASC LIMIT 1 Role Load (0.3ms) SELECT "roles".* FROM "roles" INNER JOIN "roles_users" ON "roles"."id" = "roles_users"."role_id" WHERE "roles"."deleted_at" IS NULL AND "roles_users"."user_id" = $1 [["user_id", 7]] (0.1ms) BEGIN Location Exists (0.3ms) SELECT 1 AS one FROM "locations" WHERE "locations"."identifier" = '3b7febb35ea740488788d43fcc5e989c' LIMIT 1 User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'test@test.com' LIMIT 1 (0.1ms) ROLLBACK Rendered company/new.html.erb within layouts/application (5.0ms) Completed 200 OK in 108ms (Views: 32.2ms | ActiveRecord: 1.9ms | Solr: 0.0ms) 

**公司表**

 class CreateCompanies < ActiveRecord::Migration def change create_table :companies do |t| t.string :name t.timestamps end end end 

**位置表**

 class CreateLocations < ActiveRecord::Migration def change create_table :locations do |t| t.belongs_to :company, index: true t.string :identifier t.string :name t.timestamps end end end 

**用户表**

 class CreateUsers  "Central Time (US & Canada)" t.string :avatar_file_name t.string :avatar_content_type t.integer :avatar_file_size t.datetime :avatar_updated_at ## Database authenticatable t.string :email, :null => false, :default => "" t.string :phone_number t.string :encrypted_password, :null => false, :default => "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable t.integer :sign_in_count, :default => 0 t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip t.string :last_sign_in_ip ## Token authenticatable t.string :authentication_token t.timestamps end add_index :users, :email, :unique => true add_index :users, :reset_password_token, :unique => true create_table :roles_users, :id => false do |t| t.references :role, :user end end def self.down drop_table :users drop_table :roles_users end end 

**日志中的错误**

 Started POST "/signup" for 127.0.0.1 at 2015-08-07 18:12:54 -0400 Processing by CompanyController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"aAc83zKKlV4w1i2GhTqTo3ehtXP+tPvYbBBRq1ccYzA=", "company"=>{"name"=>"Test Co.", "locations_attributes"=>{"0"=>{"name"=>"Main"}}, "users_attributes"=>{"0"=>{"first_name"=>"John", "last_name"=>"Smith", "full_name"=>"John Smith", "email"=>"john@acme.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}}, "commit"=>"Submit"} User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = 7 ORDER BY "users"."id" ASC LIMIT 1 Role Load (0.3ms) SELECT "roles".* FROM "roles" INNER JOIN "roles_users" ON "roles"."id" = "roles_users"."role_id" WHERE "roles"."deleted_at" IS NULL AND "roles_users"."user_id" = $1 [["user_id", 7]] (0.1ms) BEGIN Location Exists (0.3ms) SELECT 1 AS one FROM "locations" WHERE "locations"."identifier" = '0d759e5405084663a1c110d37f04573a' LIMIT 1 User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'john@acme.com' LIMIT 1 (0.1ms) ROLLBACK Completed 422 Unprocessable Entity in 75ms ** [Airbrake] Notice was not sent due to configuration: Environment Monitored? false API key set? true ActiveRecord::RecordInvalid (Validation failed: Locations company can't be blank): app/controllers/company_controller.rb:10:in `create' app/controllers/application_controller.rb:95:in `set_time_zone' Rendered /Users/godzilla/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.9ms) Rendered /Users/godzilla/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.7ms) Rendered /Users/godzilla/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.2ms) Rendered /Users/godzilla/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/actionpack-4.1.7/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (15.6ms) 

它引用了位置标识符已经存在,但它没有。 这是在尝试创建新Location时动态创建的(请注意location.rb模型中的方法generate_identifier )。 最重要的是,用户也不存在。

任何想法如何解决这个问题?

当您编写validates_presence_of :company这意味着您的公司记录必须在创建位置时存在,但尚未完全保存。 但是,您的位置仍与公司对象关联,并且无需此validation即可正确保存。 我认为您可以在存在company_id时进行validation,因为公司ID在保存期间可用。