Reputation: 152
I'm trying to slowly migrate an old CakePHP site to Rails 4. Because of the massive effort required, the site needs to be moved over gradually, only migrating a single piece at a time, and starting with Active Admin. I've seen plenty of questions about doing things like this, but there are a few tricky extra things I need to consider:
Once the entire site has been migrated to Rails, I can certainly start following any of the myriad number of answers about how to migrate an app to Devise, but for now I need to work with the existing app
Thanks
Upvotes: 0
Views: 1005
Reputation: 2025
I found this: http://www.slideshare.net/napcs/rails-and-legacy-databases-railsconf-2009 and followed his advise in creating sql views to wrap up the legacy table.
This is what I used to run on mine (I'm adding an application on top of Limesurvey):
CREATE VIEW `users` AS
SELECT `uid` as `id`,
`users_name` as `username`,
`email` as `email`,
`password` as `encrypted_password`,
`full_name` as `full_name`,
`role_names` as `role_names`,
`parent_id` as `parent_id`,
`lang` as `lang`,
`one_time_pw` as `one_time_pw`,
`created` as `created_at`,
`modified` as `updated_at`
FROM `lime_users`;"
The catch is that you have to include in the sql view all columns that do not have default values in the base table for you to insert into the view. This is a good way to normalize 'ugly' column names into rails-friendly column names.
My user model:
class User < ActiveRecord::Base
before_save :save_encrypted_password
self.primary_key = "id" # This needs to be declared, for some reason.
def sha2(password)
(Digest::SHA2.new << password).to_s
end
def valid_password?(password)
return false if encrypted_password.blank?
return Devise.secure_compare(sha2(password), self.encrypted_password)
end
protected
def save_encrypted_password
if password == password_confirmation
self.encrypted_password = sha2(password)
else
errors.add :password_confirmation, "has to match password"
end
end
end
It's also a good idea to reflect in the model constraints that are in the database (not null, unique values, etc) to avoid any more gotchas. (Learned this the hard way after almost an hour of slogging through arcane error messages.)
Hope this helps.
Upvotes: 0
Reputation: 152
I was able to resolve this issue by installing the ignorable gem, and SELECTing the password column AS encrypted_password in the default scope. It's ugly, but it works
class User < ActiveRecord::Base
ignore_columns :password
default_scope :select => "#{User.quoted_table_name}.*, #{User.quoted_table_name}.password AS encrypted_password"
devise :database_authenticatable
def valid_password?(password)
hash = ::Digest::MD5.hexdigest("[SALT REDACTED]#{password}").downcase
return hash == self.encrypted_password
end
end
Upvotes: 1