Additional user attributes results in UnknownAttributeError and NoMethodError

北城余情 提交于 2019-12-25 03:25:10

问题


Apologies in advance for ultra-long post, just trying to include all the info...

I have an app using Devise in which I use a rakefile to seed the database with users among other things. This worked recently, but I can't for the life of me tell what happened over the last few set of changes and it probably just needs a fresh pair of eyes.

Here's the bang-head-against-wall twist:

  • running the rakefile on localhost works correctly
  • running the rakefile after pushing to Heroku gives the errors I'll detail below
  • running the same Create commands from "heroku run rails console -a " also works correctly

Here's the user schema:

create_table "users", force: true do |t|
  t.string "email", default: "", null: false
  t.string "encrypted_password", default: "", null: false
  t.string "reset_password_token"
  t.datetime "reset_password_sent_at"
  t.datetime "remember_created_at"
  t.integer "sign_in_count", default: 0, null: false
  t.datetime "current_sign_in_at"
  t.datetime "last_sign_in_at"
  t.string "current_sign_in_ip"
  t.string "last_sign_in_ip"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string "job_title"
  t.string "first_name"
  t.string "last_name"
  t.string "confirmation_token"
  t.datetime "confirmed_at"
  t.datetime "confirmation_sent_at"
  t.string "unconfirmed_email"
  t.integer "role"
  t.integer "company_id"
  t.string "company_type"
  t.string "avatar_file_name"
  t.string "avatar_content_type"
  t.integer "avatar_file_size"
  t.datetime "avatar_updated_at"

end

And the relevant parts of the model...

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Before actions
  before_save { self.email = email.downcase }

  # Validation constants
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

  # Validation filters
  validates :email, presence: true, format: {with: VALID_EMAIL_REGEX}, uniqueness: {case_sensitive: false}
  validates :role, presence: true
  validates :company, presence: true

  # Relationships
  belongs_to :company, polymorphic: true
end

And controller stuff:

class UsersController < ApplicationController
  # Authenticate user
  before_filter :authenticate_user!

  def create
    User.create(user_params)
  end

  private
  def user_params
    params.require(:user).permit(:first_name, :last_name, :email, :encrypted_password, :job_title, :role, :company)
  end

and more...

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  # Modules to include
  include SessionsHelper

  # Before filters
  before_action :configure_permitted_parameters, if: :devise_controller?

  # Ensure authorization is setup in every action in the application
  # check_authorization

  # Devise after sign in redirect to profile page
  def after_sign_in_path_for(resource)
    "/home?login=true"
  end

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << :first_name
    devise_parameter_sanitizer.for(:sign_up) << :last_name
    devise_parameter_sanitizer.for(:sign_up) << :job_title
    devise_parameter_sanitizer.for(:sign_up) << :role
    devise_parameter_sanitizer.for(:sign_up) << :company_id
    devise_parameter_sanitizer.for(:sign_up) << :company_type

    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:first_name, :last_name, :job_title, :current_password) }
  end
end

And finally, from my rake file:

Vendor.all.each { |vendor|
  domain = EmailDomain.where(company: vendor).first.domain

  5.times do |n|
    first_name = Faker::Name.first_name
    last_name = Faker::Name.last_name
    email = "example-#{n+1}@#{domain}"
    password = "password"
    User.create!(first_name: first_name,
                    last_name: last_name,
                    email: email,
                    password: password,
                    password_confirmation: password,
                    role: User::VENDOR_USER,
                    company: vendor,
                    job_title: "Sales Manager")
  end
}

The error:

rake aborted!
ActiveRecord::UnknownAttributeError: unknown attribute: role
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:50:in `rescue in _assign_attribute'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:45:in `_assign_attribute'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:32:in `block in assign_attributes'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:26:in `each'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:26:in `assign_attributes'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/core.rb:455:in `init_attributes'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/core.rb:198:in `initialize'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/inheritance.rb:30:in `new'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/inheritance.rb:30:in `new'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/validations.rb:39:in `create!'
/app/lib/tasks/demo_data.rake:73:in `block (2 levels) in demo_create_vendors_and_users'
/app/lib/tasks/demo_data.rake:68:in `times'
/app/lib/tasks/demo_data.rake:68:in `block in demo_create_vendors_and_users'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/relation/delegation.rb:46:in `each'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/relation/delegation.rb:46:in `each'
/app/lib/tasks/demo_data.rake:64:in `demo_create_vendors_and_users'
/app/lib/tasks/demo_data.rake:5:in `block (2 levels) in <top (required)>'
NoMethodError: undefined method `role=' for #<User:0x007fcc2fb90ef8>
/app/vendor/bundle/ruby/2.1.0/gems/activemodel-4.1.5/lib/active_model/attribute_methods.rb:435:in `method_missing'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_methods.rb:208:in `method_missing'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:45:in `public_send'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:45:in `_assign_attribute'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:32:in `block in assign_attributes'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:26:in `each'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_assignment.rb:26:in `assign_attributes'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/core.rb:455:in `init_attributes'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/core.rb:198:in `initialize'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/inheritance.rb:30:in `new'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/inheritance.rb:30:in `new'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/validations.rb:39:in `create!'
/app/lib/tasks/demo_data.rake:73:in `block (2 levels) in demo_create_vendors_and_users'
/app/lib/tasks/demo_data.rake:68:in `times'
/app/lib/tasks/demo_data.rake:68:in `block in demo_create_vendors_and_users'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/relation/delegation.rb:46:in `each'
/app/vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.5/lib/active_record/relation/delegation.rb:46:in `each'
/app/lib/tasks/demo_data.rake:64:in `demo_create_vendors_and_users'
/app/lib/tasks/demo_data.rake:5:in `block (2 levels) in <top (required)>'
Tasks: TOP => demo:add_data
(See full trace by running task with --trace)

It's not specific to just role, will give the error to job_title if I rearrange the order of the parameters in the create.

One last note, among the recent changes was the overdue upgrade of many gems, including Devise from 3.2.2 to 3.3.0...seems like the project was getting away with something it no longer can. Strong parameter updates were made of late in attempt to get this to work.

来源:https://stackoverflow.com/questions/25636966/additional-user-attributes-results-in-unknownattributeerror-and-nomethoderror

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!