Rails rollback when creating user with nested forms -
i'm getting rollback when trying add user db , i'm not sure why.
i have 3 models: 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 < activerecord::base acts_as_paranoid belongs_to :company has_many :network_hosts, dependent: :destroy has_many :tests, dependent: :destroy has_many :commands, dependent: :destroy validates_presence_of :company, :identifier, :name validates_uniqueness_of :identifier delegate :security_percentage, to: :last_test, allow_nil: true after_initialize :generate_identifier, if: -> { self.identifier.blank? } def generate_identifier self.identifier = securerandom.uuid.delete("-") end
so, when user wants signup need enter company, location, , user information, controlled 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
the form using standard form_for
nested attributes can make in 1 shot when user clicks submit button
** company/new.html.erb **
<%= form_for @company, :url => url_for( :controller => 'company', :action => 'new' ) |f| %> <div class="form-group"> <%= f.label "company name" %> <%= f.text_field :name, class: "form-control", placeholder: "acme inc." %> <%= f.fields_for :locations | location_builder | %> <%= location_builder.label "location name" %> <%= location_builder.text_field :name, class: "form-control", placeholder: "main building" %> <% end %> </div> <div class="form-group"> <%= f.fields_for :users | user_builder | %> <%= user_builder.label "first name" %> <%= user_builder.text_field :first_name, class: "form-control", placeholder: "john" %> <%= user_builder.label "last name" %> <%= user_builder.text_field :last_name, class: "form-control", placeholder: "smith" %> <%= user_builder.label "full name" %> <%= user_builder.text_field :full_name, class: "form-control", placeholder: "john smith" %> <%= user_builder.label "email" %> <%= user_builder.email_field :email, class: "form-control", placeholder: "john@acme.com" %> <%= user_builder.label "password" %> <%= user_builder.password_field :password, class: "form-control" %> <%= user_builder.label "confirm password" %> <%= user_builder.password_field :password_confirmation, class: "form-control" %> <% end %> </div> <%= f.submit "submit", class: "btn btn-large btn-success" %> <% end %>
however, i'm getting rollback in logs isn't happening , can't figure out why.
started post "/signup" 127.0.0.1 @ 2015-08-07 13:49:22 -0400 processing companycontroller#create 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".* "users" "users"."deleted_at" null , "users"."id" = 7 order "users"."id" asc limit 1 role load (0.3ms) select "roles".* "roles" inner join "roles_users" on "roles"."id" = "roles_users"."role_id" "roles"."deleted_at" null , "roles_users"."user_id" = $1 [["user_id", 7]] (0.1ms) begin location exists (0.3ms) select 1 one "locations" "locations"."identifier" = '3b7febb35ea740488788d43fcc5e989c' limit 1 user exists (0.3ms) select 1 one "users" "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)
** company table **
class createcompanies < activerecord::migration def change create_table :companies |t| t.string :name t.timestamps end end end
** location table **
class createlocations < activerecord::migration def change create_table :locations |t| t.belongs_to :company, index: true t.string :identifier t.string :name t.timestamps end end end
** user table **
class createusers < activerecord::migration def self.up create_table(:users) |t| t.belongs_to :company, index: true t.string :username t.string :first_name t.string :last_name t.string :full_name t.string :time_zone, :default => "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 |t| t.references :role, :user end end def self.down drop_table :users drop_table :roles_users end end
** error logs **
started post "/signup" 127.0.0.1 @ 2015-08-07 18:12:54 -0400 processing companycontroller#create 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".* "users" "users"."deleted_at" null , "users"."id" = 7 order "users"."id" asc limit 1 role load (0.3ms) select "roles".* "roles" inner join "roles_users" on "roles"."id" = "roles_users"."role_id" "roles"."deleted_at" null , "roles_users"."user_id" = $1 [["user_id", 7]] (0.1ms) begin location exists (0.3ms) select 1 one "locations" "locations"."identifier" = '0d759e5405084663a1c110d37f04573a' limit 1 user exists (0.2ms) select 1 one "users" "users"."email" = 'john@acme.com' limit 1 (0.1ms) rollback completed 422 unprocessable entity in 75ms ** [airbrake] notice not sent due configuration: environment monitored? false api key set? true activerecord::recordinvalid (validation failed: locations company can't 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)
it references location identifier exists, doesn't. made on fly when trying create new location
(notice method generate_identifier
in location.rb
model). on top of that, user doesn't exist either.
any ideas how around problem?
when write validates_presence_of :company
means company record has exist @ time of location creation, not saved yet. however, location still associated company object, , saved correctly without validation. think can validate on presence of company_id instead because company id becomes available during saving.
Comments
Post a Comment