Beginner ruby/rails question here. I have a method That I am currently using in my "User" model.
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
I want to reuse the same method in a different model say my Account model.
Where is a good place to put code like this to be shared between models? Also, in order to get the calling class would I just use "self.class"?
Thanks
Rails 4 concerns
are here to do this job. http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
app/models/user.rb
:
class User < ActiveRecord::Base
include TokenGenerator
def foo
$stderr.puts self.class.generate_token("bar")
end
end
app/models/account.rb
:
class Account < ActiveRecord::Base
include TokenGenerator
class << self
def bar
return generate_token("foo")
end
end
end
app/models/concerns/token_generator.rb
module TokenGenerator
extend ActiveSupport::Concern
module ClassMethods
def generate_token(c)
return "some_thing"
end
end
end
If you are ever writing the same method twice, you are right that it's probably a sign of writing bad code. If it were me, I would create an abstract class that is a parent class to both Account and User. Make Account and User inherit from this parent class, and put all of the shared logic in that parent class. Then Account and User will automatically have access to that shared logic.
You will want to look up how to make abstract classes in rails. Once you've made the new parent abstract class, make sure Account and User inherit from the parent class instead of ActiveRecord::Base like so:
class Account < NewAbstractClass
end
class user < NewAbstratClass
end
I am neither agreeing nor disagreeing with the above or below answers, through using concerns or through using modules. However, this is the way that I have solved this problem before in the past, and this is a good object orient way to try and solve the problem of shared logic between multiple classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With