0

I've got TWO apps...an old Rails 2.3.14 app and the same code updated to Rails 3.1.0. (I know 6.x is recent but I'm taking small steps first)

I'm testing both apps against the same postgres database in turns

When I run the 2.3 app in console and pull up Rails console I get a result...

>> User.first
=> #<User id: 433, login: "danny.vally", email: "danny.vally@gmail.com", crypted_password: "xxxxxxxxxxxxxxxxxxxxxxx", salt: "yyyyyyyyyyyyyyyyyyyyyyyy", created_at: "2015-12-11 10:56:17", updated_at: "2016-10-01 00:00:23", remember_token: nil, remember_token_expires_at: nil, contact_id: 1222222, created_by: 333, updated_by: 434, cashier_code: 9555, can_login: false, last_logged_in: "2016-03-05", shared: false, reason_cannot_login: "Account disabled due to 280 days of inactivity.">

Great...I can see the DB and see a user in the User model.

Now, on the Rails 3.1.0 version (pointing to the same DB...after exiting the other app)....I get the following in rails console...

$ rails c
/home/fonso/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/soap4r-ruby1.9-2.0.5/lib/xsd/iconvcharset.rb:9:in `<top (required)>': iconv will be deprecated in the future, use String#encode instead.
/home/fonso/.rbenv/versions/1.9.3-p551/lib/ruby/gems/1.9.1/gems/12_hour_time-0.0.4/lib/12_hour_time/action_view_helpers.rb:3: warning: already initialized constant POSITION
Loading development environment (Rails 3.1.0)
irb(main):001:0> User.first
  User Load (0.7ms)  SELECT "users".* FROM "users" LIMIT 1
   (0.1ms)  SHOW search_path
  User Indexes (1.1ms)   SELECT distinct i.relname, d.indisunique, d.indkey, t.oid
 FROM pg_class t
 INNER JOIN pg_index d ON t.oid = d.indrelid
 INNER JOIN pg_class i ON d.indexrelid = i.oid
 WHERE i.relkind = 'i'
 AND d.indisprimary = 'f'
 AND t.relname = 'users'
 AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN ('"$user"','public') )
 ORDER BY i.relname

  User Indexes (0.4ms)   SELECT c2.relname, i.indisunique, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)
 FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
 WHERE c.relname = 'users'
 AND c.oid = i.indrelid AND i.indexrelid = c2.oid
 AND i.indisprimary = 'f'
 AND i.indexprs IS NOT NULL
 ORDER BY 1

(Object doesn't support #inspect)
=>
irb(main):002:0>

Here is the User model is that helps ...

class User < ActiveRecord::Base
  Rails.logger.debug "User Model called"
  acts_as_userstamp
  has_and_belongs_to_many :roles

  # Virtual attribute for the unencrypted password
  attr_accessor :password

  validates_presence_of     :login, :email
  validates_presence_of     :password,                   :if => :password_required?
  validates_presence_of     :password_confirmation,      :if => :password_required?
  validates_length_of       :password, :within => 4..40, :if => :password_required?, :allow_nil => true
  validates_confirmation_of :password,                   :if => :password_required?
  validates_length_of       :login,    :within => 3..40, :allow_nil => true
  validates_length_of       :email,    :within => 3..100, :allow_nil => true
  validates_uniqueness_of   :login, :email, :case_sensitive => false
  validates_uniqueness_of   :cashier_code, :if => :cashier_code
  validates_format_of       :login, :with => /[^0-9]/, :message => "must contain a non-numeric character"
  before_save :encrypt_password
  before_save :add_cashier_code
  before_save :disable_reason_cannot_login_on_reenable

  def disable_reason_cannot_login_on_reenable
    return unless self.can_login && self.can_login_changed?
    self.reason_cannot_login = "" if self.reason_cannot_login && self.reason_cannot_login.length > 0
  end

  belongs_to :contact
  has_one :skedjulnator_access


  # attr_accessible :login, :email, :password, :password_confirmation, :can_login, :shared
  # S.O. says this line will not work for Rails 3.1
  # https://stackoverflow.com/questions/68291144/can-not-seem-to-pull-out-the-attributes-of-this-object


  scope :can_login, {:conditions => ["can_login = 't'"]}

  def self.hidden_columns
    super + [:crypted_password, :salt]
  end

  def can_view_disciplinary_information?
    !! (self.contact and self.contact.worker and self.contact.worker.worker_type_today and self.contact.worker.worker_type_today.name != 'inactive')
  end

  def update_skedjulnator_access_time
    self.skedjulnator_access ||= SkedjulnatorAccess.new
    self.skedjulnator_access.user_id_will_change!
    self.skedjulnator_access.save!
  end

  def grantable_roles
    self.roles.include?(Role.find_by_name('ADMIN')) ? Role.find(:all) : self.roles
  end


  def self.reset_all_cashier_codes
    self.find(:all).each{|x|
      x.reset_cashier_code
      x.save
    }
  end

  def contact_display_name
    self.contact ? self.contact.display_name : self.login
  end

  def add_cashier_code
    reset_cashier_code if !self.shared and cashier_code.nil?
  end

  def reset_cashier_code
    valid_codes = (1000..9999).to_a - User.find(:all).collect{|x| x.cashier_code}
    my_code = valid_codes[rand(valid_codes.length)]
    self.cashier_code = my_code
  end

  def merge_in(other)
    for i in [:actions, :donations, :sales, :types, :users, :volunteer_tasks, :contacts, :gizmo_returns]
      User.connection.execute("UPDATE #{i.to_s} SET created_by = #{self.id} WHERE created_by = #{other.id}")
      User.connection.execute("UPDATE #{i.to_s} SET updated_by = #{self.id} WHERE updated_by = #{other.id}")
    end
    ["donations", "sales", "volunteer_tasks", "disbursements", "recyclings", "contacts"].each{|x|
      User.connection.execute("UPDATE #{x.to_s} SET cashier_created_by = #{self.id} WHERE cashier_created_by = #{other.id}")
      User.connection.execute("UPDATE #{x.to_s} SET cashier_updated_by = #{self.id} WHERE cashier_updated_by = #{other.id}")
    }
    self.roles = (self.roles + other.roles).uniq
    self.save!
  end

  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
  def self.authenticate(login, password)
    if login.to_i.to_s == login
      u = find_by_contact_id(login.to_i)
    else
      u = find_by_login(login) # need to get the salt
    end
    return u if u && u.can_login && u.authenticated?(password)
    return nil
  end

  # Encrypts some data with the salt.
  def self.encrypt(password, salt)
    Digest::SHA1.hexdigest("--#{salt}--#{password}--")
  end

  # Encrypts the password with the user salt
  def encrypt(password)
    self.class.encrypt(password, salt)
  end

  def authenticated?(password)
    crypted_password == encrypt(password)
  end

  def remember_token?
    remember_token_expires_at && Time.now.utc < remember_token_expires_at
  end

  # These create and unset the fields required for remembering users between browser closes
  def remember_me
    remember_me_for 2.weeks
  end

  def remember_me_for(time)
    remember_me_until time.from_now.utc
  end

  def remember_me_until(time)
    self.remember_token_expires_at = time
    self.remember_token            = encrypt("#{email}--#{remember_token_expires_at}")
    save(false)
  end

  def forget_me
    self.remember_token_expires_at = nil
    self.remember_token            = nil
    save(false)
  end

  # start auth junk

  def User.current_user
    Thread.current['user'] || User.fake_new
  end

  attr_accessor :fake_logged_in

  def User.fake_new
    u = User.new
    u.fake_logged_in = true
    u
  end

  def logged_in
    ! fake_logged_in
  end

  def to_privileges
    return "logged_in" if self.logged_in
  end

  def privileges
    @privileges ||= _privileges
  end

  def _privileges
    olda = []
    return olda if !self.can_login
    a = [self, self.contact, self.contact ? self.contact.worker : nil, self.roles].flatten.select{|x| !x.nil?}.map{|x| x.to_privileges}.flatten.select{|x| !x.nil?}.map{|x| Privilege.by_name(x)}
    while olda != a
      a = a.select{|x| !x.restrict} if self.shared
      olda = a.dup
      a << olda.map{|x| x.children}.flatten
      a = a.flatten.sort_by(&:name).uniq
      a = a.select{|x| !x.restrict} if self.shared
    end
    a = a.map{|x| x.name}
    a
  end

  def has_privileges(*privs)
    positive_privs = []
    negative_privs = []
    privs.flatten!
    for i in privs
      if i.match(/^!/)
        negative_privs << i.sub(/^!/, "")
      else
        positive_privs << i
      end
    end
    if positive_privs.length > 0
      positive_privs << "role_admin"
    end
    if negative_privs.length > 0
      negative_privs << "role_admin"
    end
    my_privs = self.privileges
    #puts "NEG: #{negative_privs.inspect}, POS: #{positive_privs.inspect}, MY: #{my_privs.inspect}"
    return (negative_privs & my_privs).length == 0 && ((positive_privs & my_privs).length > 0 || positive_privs.length == 0)
  end

  # end auth junk

  protected
  # before filter
  def encrypt_password
    return if password.blank?
    self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
    self.crypted_password = encrypt(password)
  end

  def password_required?
    crypted_password.blank? || !password.blank?
  end

end

I've been pouring over this for weeks but I'm stumped. Is there any hope? Is this some sort of glitch in 3.1.0 that might have been fixed in some later version? Maybe 3.1.1? Or is it impossible to upgrade from 2.3.14 to 3.1.0?

Thank you for your time.

thefonso
  • 3,220
  • 6
  • 37
  • 54
  • Probably have found most of these posts already, does this give you a thread to pull? https://stackoverflow.com/questions/7690697/object-doesnt-support-inspect – Rockwell Rice Jul 13 '21 at 03:35
  • @RockwellRice hmm...I've looked at that one and I'm not sure. Also, I see in this model a method to_s ... like why is that method named to_s, wouldn't that conflict with the regular rails to_s method? – thefonso Jul 13 '21 at 04:34
  • 1
    Try commenting out that `to_s`, it could be what's interfering with `inspect` so you don't see the output in console. I don't see any error by the way, so I think it's just that the user object in console ... if you did `User.first.id` I bet it would work. And yeah, patching `to_s` to do `login` makes zero sense whatsoever – max pleaner Jul 13 '21 at 05:16
  • @maxpleaner I removed that to_s from the model and still got the same output. I've updated the code in the question accordingly – thefonso Jul 13 '21 at 06:49
  • 1
    One thing that I would try is to comment everything in the model, just leave `class User < ActiveRecord::Base`, then start uncommenting pieces of code until you see that #inspect issue. – Alter Lagos Jul 13 '21 at 09:35

0 Answers0