Jump to content

The ultimate community for Ruby on Rails developers.


Photo

Devise issues with STI - type field for model changing unexpectedly on logon.

devise

  • Please log in to reply
No replies to this topic

#1 VicVol

VicVol

    Passenger

  • Members
  • 1 posts

Posted 10 December 2013 - 08:39 PM

We are using Rails 3.2.15 with Devise 3.2.0. We followed a tutorial to use Devise with STI (Single Table Inheritance). The STI appears to be working properly, but we have a strange issue where, after logon to the site, a user of a specific model is having their type field change without reason (that we can find). 

 

Our site is currently very simple, with little added beyond the default controllers and views (we have deployed some additional gems, like rolify and CanCan, but have done nothing with them as of yet). Devise is installed on the default User model as instructed in the walkthrough, and we have two additional models for users, Fan and Artist. All users who sign up to our site are to be either a Fan or Artist. Both the Fan and Artist models inherit from User (as in, Fan < User and Artist < User), as is standard with STI. The root User model includes a type field, which is set properly to Fan or Artist when we call Fan.create() or Artist.create() (as confirmed via the rails console).

 

Right now we have a single Fan (created via rails console with Fan.create()), which has user ID 11, and a single Artist (created via rails console with Artist.create()), which has user ID 10. If via rails console, we call User.find(11).type, it returns 'Fan' properly, as seen here:

 
2.0.0-p247 :003 > User.find(11).type
  User Load (0.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 11 LIMIT 1
 => "Fan" 
 
The same thing works for the lone Artist, as seen here:
 
2.0.0-p247 :004 > User.find(10).type
  User Load (0.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 10 LIMIT 1
 => "Artist"
 
However, if the Fan or Artist authenticates to the site via the default Devise /user/sign_in forms, once authenticated, the Fan account switches type from Fan to Artist. It is incredibly odd, and we cannot figure out why. As stated, other than our models, we have added very little code to the application at this point, with no additional actions added to the three controllers we have (home, dashboard, and the default application). I added some debugging code to the default dashboard index view to demonstrate the issue we are having in real time, which is shown below.
 
This is the output from when we added User.find(current_user.id).inspect, current_user.inspect, and current_user.changes.inspect to the default index view of the dashboard when the Fan account authenticates (email, password hash, and sign_in IPs have been obfuscated for security purposes):
 
User.find(current_user.id).inspect: #<Fan id: 11, email: "test@test.com", encrypted_password: "$2a$10$zBeLw2FhESE7...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 5, current_sign_in_at: "2013-12-10 00:06:45", last_sign_in_at: "2013-12-08 18:27:59", current_sign_in_ip: "192.168.1.100", last_sign_in_ip: "192.168.1.100", created_at: "2013-12-08 03:54:33", updated_at: "2013-12-10 00:06:45", first_name: "test", last_name: "fan", username: "testf", type: "Fan", birthday: nil, confirmation_token: nil, confirmed_at: "2013-12-08 03:55:09", confirmation_sent_at: "2013-12-08 03:54:33", unconfirmed_email: nil>
 
current_user.inspect: #<Fan id: 11, email: "test@test.com", encrypted_password: "$2a$10$zBeLw2FhESE7...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 5, current_sign_in_at: "2013-12-10 00:06:45", last_sign_in_at: "2013-12-08 18:27:59", current_sign_in_ip: "192.168.1.100", last_sign_in_ip: "192.168.1.100", created_at: "2013-12-08 03:54:33", updated_at: "2013-12-10 00:06:45", first_name: "test", last_name: "fan", username: "testf", type: "Artist", birthday: nil, confirmation_token: nil, confirmed_at: "2013-12-08 03:55:09", confirmation_sent_at: "2013-12-08 03:54:33", unconfirmed_email: nil>
 
current_user.changes.inspect: {"type"=>["Fan", "Artist"]}
 
Please notice how User.find(current_user.id).inspect says type is set to 'Fan' as expected, yet current_user.inspect says type is set to 'Artist', and no other fields are different between the two. Also notice how current_user.changes.inspect specifically shows that, for some unknown reason, the type field on current_user is being changed from 'Fan' to 'Artist'. Please note that if you log in as the lone Artist account, there are no differences between User.find(current_user.id).inspect and current_user.inspect (the type field is 'Artist' as expected), and current_user.changes.inspect returns nothing, since nothing has changed. 
 
Below is our User model, Fan model, and Artist model. 
 
user.rb:
 
class User < ActiveRecord::Base
  rolify
 
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable
 
  attr_accessible :username, :first_name, :last_name, :email, :password, :password_confirmation, :remember_me, :birthday
 
  attr_protected :type
  validates_presence_of :first_name, :last_name, :username
  validates_uniqueness_of :username, :email, :case_sensitive => false
 
end
 
fan.rb:
 
class Fan < User
 
  has_one :fan_profile
 
end
 
artist.rb:
 
class Artist < User
 
  has_one :artist_profile
  has_many :artist_posts
  has_and_belongs_to_many :genres
 
end
 

 

If there is any other data required from our project, please do not hesitate to let us know. We greatly appreciate assistance, as we have been scratching our heads over this for days and asking support channels on IRC.







Also tagged with one or more of these keywords: devise

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users