Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to extend ActiveRecord::Migration with additional methods?
    text
    copied!<p>I'm creating a Ruby gem and would like to extend ActiveRecord::Migration with my own helpers for creating the necessary columns. (This is similar to what Devise does when creating migrations for their various authentication strategies.) I realize the functionality I'm adding is pretty trivial itself and there are probably better/more efficient ways of doing this - I'm attempting this as a learning experience rather than as something with practical application. I just want to understand how to do something as invasive as adding new migration capabilities in Rails.</p> <p>What I have so far builds into a gem successfully and installs, but when I attempt to run a migration like:</p> <pre><code>class CreatePosts &lt; ActiveRecord::Migration def self.up create_table :posts do |t| t.string :name t.string :title t.text :content t.hideable t.tracks_hidden_at t.timestamps end end end </code></pre> <p>... it fails saying that hideable isn't defined.</p> <p>I've looked into the way that Devise has done this and I have to admit I'm a little lost, but I've tried to fumble through it. I've done the following:</p> <p><strong>Extended ActiveRecord with my new model additions and created a method to apply the schema changes based on my new migration methods</strong></p> <pre><code>require 'orm_adapter/adapters/active_record' module HiddenRecord module Orm # This module contains some helpers and handle schema (migrations): # # create_table :accounts do |t| # t.hideable # t.tracks_hidden_timestamp # end # module ActiveRecord module Schema include HiddenRecord::Schema # Tell how to apply schema methods. def apply_hiddenrecord_schema(name, type, options={}) column name, type.to_s.downcase.to_sym, options end end end end end ActiveRecord::Base.extend HiddenRecord::Models ActiveRecord::ConnectionAdapters::Table.send :include, HiddenRecord::Orm::ActiveRecord::Schema ActiveRecord::ConnectionAdapters::TableDefinition.send :include, HiddenRecord::Orm::ActiveRecord::Schema </code></pre> <p><strong>Created a Schema module similar to Devise's schema.rb that defines the methods I want to use in the migration and calls a method to apply the schema</strong></p> <pre><code>module HiddenRecord # Holds schema definition for hiddenrecord model options. module Schema # Sets the model as having hidable rows # # == Options # * :null - When true, allows the hidden row flag to be null # * :default - Used to set default hidden status to true. If not set, default is false (rows are not hidden) def hideable(options={}) null = options[:null] || false default = options[:default] || false apply_hiddenrecord_schema :hiddenrecord_is_row_hidden, Boolean, :null =&gt; null, :default =&gt; default end # Sets the model to record the timestamp when a row was hidden def tracks_hidden_timestamp() apply_hiddenrecord_schema :hiddenrecord_hidden_at, DateTime end end end </code></pre> <p><strong>Added methods for the models to support the new fields</strong></p> <pre><code>module HiddenRecord module Models # This module implements the hideable API module Hideable def self.included(base) base.class_eval do extend ClassMethods end end scope :visible, where(:hiddenrecord_is_row_hidden =&gt; true) def hidden? return hiddenrecord_is_row_hidden || false end def hide hiddenrecord_is_row_hidden = true end def hide! hiddenrecord_is_row_hidden = true save! end def unhide hiddenrecord_is_row_hidden = false end def unhide! hiddenrecord_is_row_hidden = false save! end end end end </code></pre> <p><strong>Load the schema and model files and in the main module of the gem</strong></p> <pre><code>module HiddenRecord autoload :Schema, 'hiddenrecord/schema' autoload :Models, 'hiddenrecord/models' ... end require 'hiddenrecord/models/hideable' require 'hiddenrecord/models/tracks_hidden_timestamp' </code></pre> <p>Again, recognizing that this is primarily a learning experience, I'm hoping someone can point me in the right direction on how to do this. I'm attempting this on Rails 3.</p>
 

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