Estoy creando una gema Ruby y me gustaría extender ActiveRecord :: Migration con mis propios ayudantes para crear las columnas necesarias. (Esto es similar a lo que hace Devise al crear migraciones para sus diversas estrategias de autenticación.) Me doy cuenta de que la funcionalidad que agrego es bastante trivial y probablemente haya formas mejores/más eficientes de hacerlo. Estoy intentando esto como una experiencia de aprendizaje más que como algo con aplicación práctica. Solo quiero entender cómo hacer algo tan invasivo como agregar nuevas capacidades de migración en Rails.¿Cómo extender ActiveRecord :: Migration con métodos adicionales?
Lo que tengo hasta ahora se basa en una joya con éxito y se instala, pero cuando intento ejecutar una migración como:
class CreatePosts < 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
... se produce un error diciendo que hideable no está definido.
He visto la forma en que Devise ha hecho esto y tengo que admitir que estoy un poco perdido, pero he tratado de buscarlo. Yo he hecho lo siguiente:
ActiveRecord extendido con mis nuevas adiciones modelo y ha creado un método para aplicar los cambios de esquema basado en mis nuevos métodos de migración
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
Creado un módulo de esquema similar al Idear de schema.rb que define los métodos que desea utilizar en la migración y llama a un método para aplicar el esquema
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 => null, :default => 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
métodos añadido para los modelos de apoyo a los nuevos campos
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 => 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
Cargar los archivos de esquema y el modelo y en el módulo principal de la gema
module HiddenRecord
autoload :Schema, 'hiddenrecord/schema'
autoload :Models, 'hiddenrecord/models'
...
end
require 'hiddenrecord/models/hideable'
require 'hiddenrecord/models/tracks_hidden_timestamp'
Una vez más, reconociendo que esto es principalmente una experiencia de aprendizaje, espero que alguien pueda señalarme en la dirección correcta sobre cómo hacer esto. Estoy intentando esto en Rails 3.
Dicho sea de paso, si usa este código para SECAR en migraciones, puede indicar un olor a código porque está repitiendo campos en todo su modelo de datos.Puede indicar que debe normalizar su modelo de datos para reducir la duplicación. – BlueFish