hzamani / acts_as_relation

Multi table Inheritance for rails
http://hzamani.github.com/acts_as_relation/
MIT License
180 stars 58 forks source link

Extending Devise's User to Roles using acts_as_relation #51

Open toobulkeh opened 10 years ago

toobulkeh commented 10 years ago

I left this similar comment on devise's repository, to hopefully see a larger target audience. I'll copy and paste it here to reach another audience while linking to the original.

To make a long story short, I'm attempting to use MTI to create different roles in an application. While this isn't really documented well anywhere, I was hoping to combine the two models that I see as "best practice" (for lack of a better term).

My current issue is when creating or logging into the system using devise, devise seems to query ActiveRecord for specific column names, instead of using ruby attribute calls.

That is, when I try to login to the system, I receive a column not found:

SQLite3::SQLException: no such column: customers.email: SELECT  "customers"."id" AS t0_r0, "customers"."created_at" AS t0_r1, "customers"."updated_at" AS t0_r2, "users"."id" AS t1_r0, "users"."as_user_id" AS t1_r1, "users"."as_user_type" AS t1_r2, "users"."email" AS t1_r3, "users"."encrypted_password" AS t1_r4, "users"."reset_password_token" AS t1_r5, "users"."reset_password_sent_at" AS t1_r6, "users"."remember_created_at" AS t1_r7, "users"."sign_in_count" AS t1_r8, "users"."current_sign_in_at" AS t1_r9, "users"."last_sign_in_at" AS t1_r10, "users"."current_sign_in_ip" AS t1_r11, "users"."last_sign_in_ip" AS t1_r12, "users"."created_at" AS t1_r13, "users"."updated_at" AS t1_r14 FROM "customers" INNER JOIN "users" ON "users"."as_user_id" = "customers"."id" AND "users"."as_user_type" = 'Customer' WHERE "customers"."email" = 'testcustomer@test.com' LIMIT 1

and when I try to sign up, I receive what appears to be a validation problem:

NoMethodError (undefined method `text?' for nil:NilClass):
  activerecord (3.2.15) lib/active_record/validations/uniqueness.rb:57:in `build_relation'
  activerecord (3.2.15) lib/active_record/validations/uniqueness.rb:25:in `validate_each'
  activemodel (3.2.15) lib/active_model/validator.rb:153:in `block in validate'
  activemodel (3.2.15) lib/active_model/validator.rb:150:in `each'
  activemodel (3.2.15) lib/active_model/validator.rb:150:in `validate'
  activesupport (3.2.15) lib/active_support/callbacks.rb:310:in `_callback_before_55'
  activesupport (3.2.15) lib/active_support/callbacks.rb:429:in `_run__2666856343956316215__validate__3987179287797953709__callbacks'
  activesupport (3.2.15) lib/active_support/callbacks.rb:405:in `__run_callback'
  activesupport (3.2.15) lib/active_support/callbacks.rb:385:in `_run_validate_callbacks'
  activesupport (3.2.15) lib/active_support/callbacks.rb:81:in `run_callbacks'
  activemodel (3.2.15) lib/active_model/validations.rb:228:in `run_validations!'
  activemodel (3.2.15) lib/active_model/validations/callbacks.rb:53:in `block in run_validations!'
  activesupport (3.2.15) lib/active_support/callbacks.rb:425:in `_run__2666856343956316215__validation__3987179287797953709__callbacks'
  activesupport (3.2.15) lib/active_support/callbacks.rb:405:in `__run_callback'
  activesupport (3.2.15) lib/active_support/callbacks.rb:385:in `_run_validation_callbacks'
  activesupport (3.2.15) lib/active_support/callbacks.rb:81:in `run_callbacks'
  activemodel (3.2.15) lib/active_model/validations/callbacks.rb:53:in `run_validations!'
  activemodel (3.2.15) lib/active_model/validations.rb:195:in `valid?'
  activerecord (3.2.15) lib/active_record/validations.rb:69:in `valid?'
  activerecord (3.2.15) lib/active_record/validations.rb:77:in `perform_validations'
  activerecord (3.2.15) lib/active_record/validations.rb:50:in `save'
  activerecord (3.2.15) lib/active_record/attribute_methods/dirty.rb:22:in `save'
  activerecord (3.2.15) lib/active_record/transactions.rb:259:in `block (2 levels) in save'
  activerecord (3.2.15) lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
  activerecord (3.2.15) lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
  activerecord (3.2.15) lib/active_record/transactions.rb:208:in `transaction'
  activerecord (3.2.15) lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
  activerecord (3.2.15) lib/active_record/transactions.rb:259:in `block in save'
  activerecord (3.2.15) lib/active_record/transactions.rb:270:in `rollback_active_record_state!'
  activerecord (3.2.15) lib/active_record/transactions.rb:258:in `save'
  devise (3.1.1) app/controllers/devise/registrations_controller.rb:15:in `create'

To me, this looks like devise is relying on activerecord directly instead of the models I've since created. Is there a way to change this functionality or is there a reason it is written this way?

For reference, my routes is devise_for :customers my user.rb:

class User < ActiveRecord::Base
  #Multi-Table Inheritance. A user can be a Customer, Employee, or an Admin
  acts_as_superclass

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

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me
  # attr_accessible :title, :body
end

my customer:

class Customer < ActiveRecord::Base
  acts_as :user

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  attr_accessible :email, :password, :password_confirmation, :remember_me

end

(side note: I noticed that you need the devise statements here for the routes to generate properly, and the attr_accessible was added to see if that would permit devise to access the proper variables, to no avail)

and my related schema:

  create_table "customers", :force => true do |t|
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "users", :force => true do |t|
    t.integer  "as_user_id"
    t.string   "as_user_type"
    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",                             :null => false
    t.datetime "updated_at",                             :null => false
  end

  add_index "users", ["email"], :name => "index_users_on_email", :unique => true
  add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true

Thanks for listening!

Original post: https://github.com/plataformatec/devise/issues/2712

uchoaaa commented 10 years ago

Any news about this issue?!