Rails: Preserving DRY with ActiveRecord Models That Have Similar Complex Attributes

It seems like it should have a direct answer, but after a long time on Google and SO I can't find it. This may be the case of the absence of the right keywords.

In my RoR application, I have several models that have a certain type of string attribute that has special validation and other functions. The closest similar example that I can think of is a string representing a URL.

This leads to a lot of duplication in models (and even more duplication in unit tests), but I'm not sure how to make it drier.

I can think of several possible directions ...

  • create a plugin along the lines of the plugin "validates_url_format_of" but this would make DRY validations
  • give this special line its own model, but it seems like a very heavy solution
  • create a ruby ​​class for this special string, but how do I get an ActiveRecord to bind this class to a model attribute, which is a string in db

Number 3 seems the most reasonable, but I can’t figure out how to extend ActiveRecord to handle everything except the underlying data types. Any pointers?

Finally, if there is a way to do this, where in the folder hierarchy do you put a new class that is not a model?

Many thanks.

UPDATE

One potential solution using the Matt mixin clause below (and using an example URL). Note that this is closer to psuedocode than a real ruby, and is intended to convey the principle, not the perfect syntax.

First create a mix url:

module Url
  def url_well_formed?
    [...]
  end

  def url_live?
    [...]
  end
end

Site :

Class Site < ActiveRecord:Base
  include Url

  validate :url_well_formed?
end

, URL- , ...

if site.url_live?
  [...]
end

, , - DRY. , Page, mixin url, URL - . , , .

, , ?

+5
2

:

class CommonBase < ActiveRecord::Base
  self.abstract_class = true # makes the model abstract
  validate_format_of :url_field, :with => /.../
end

:

class User < CommonBase
end

class Post < CommonBase
end
+6

? Google mixins.

+2

All Articles