Note that there are some explanatory texts on larger screens.

plurals
  1. POWrapping ActiveRecord methods with additional functionality
    primarykey
    data
    text
    <p>I want to enhance the ActiveRecord setters in Rails to ensure only valid values are saved. One such place where this is needed is phone numbers. A user may enter a phone number in a variety of formats such as,</p> <pre><code>(123) 456-7890 +1 123-456-7890 </code></pre> <p>but I only want to store the digits and discard the rest when it goes to the database. The approach I am using right now is to override the setter methods using <code>alias_method</code>. Also, I am trying to put this into a module so any model class that contains phone number can include this module, and define the fields that should be cleaned up. The kind of interface I am hoping to use is,</p> <pre><code># Person has a "phone" attribute to store phone numbers class Person &lt; ActiveRecord::Base # first include this module include PhoneSanitizer # then call the class method and tell it which # fields need need to be sanitized sanitize_phone_field :phone end </code></pre> <p>The only thing I'm doing inside my model classes is to include the <code>PhoneSanitizer</code> module (which adds a class method - <code>sanitize_phone_field</code> in the <code>Person</code> class). That method is now responsible for overriding the setter <code>phone=</code> method. This is the part I haven't gotten to work.</p> <pre><code>module PhoneSanitizer module ClassMethods # wrap each of the passed-in fields with setters that # clean up the phone number value of non-digits. def sanitize_phone(*fields) fields.each do |field| new_method = "original_#{field}=".to_sym original_method = "#{field}=".to_sym alias_method new_method, original_method define_method(original_method) do |value| self.send(new_method, phone_to_number(value)) end end end end def self.included(base) base.extend(ClassMethods) end def phone_to_number(number) number.gsub(/[^\d]/, '') end end </code></pre> <p>When <code>sanitize_phone</code> is called, it throws an error saying <code>:phone=</code> is not defined for the <code>Person</code> class, and that makes sense. How would I go about aliasing the method for the instances of Person instead?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload