Sto creando una gemma Ruby e vorrei estendere ActiveRecord :: Migration con i miei aiutanti per creare le colonne necessarie. (Questo è simile a ciò che Devise fa quando crea le migrazioni per le loro varie strategie di autenticazione.) Mi rendo conto che la funzionalità che sto aggiungendo è piuttosto banale e ci sono probabilmente modi migliori/più efficienti per farlo - sto provando questo esperienza di apprendimento piuttosto che come qualcosa con applicazione pratica. Voglio solo capire come fare qualcosa di così invasivo come aggiungere nuove funzionalità di migrazione in Rails.Come estendere ActiveRecord :: Migration con metodi aggiuntivi?
Quello che ho costruisce finora in un gioiello con successo e monta, ma quando si tenta di eseguire una migrazione simile:
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
... fallisce dicendo che hideable non è definito.
Ho esaminato il modo in cui Devise ha fatto questo e devo ammettere che sono un po 'perso, ma ho cercato di armeggiare. Ho fatto quanto segue:
esteso ActiveRecord con le mie nuove aggiunte modello e ha creato un metodo per applicare le modifiche dello schema in base alle mie nuove metodologie di migrazione
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
Creato un modulo schema simile di escogitare di schema.rb che definisce i metodi che voglio utilizzare nella migrazione e chiama un metodo per applicare lo schema
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
metodi aggiunto per i modelli per supportare i nuovi campi
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
Caricare i file di schema e il modello e il modulo principale della gemma
module HiddenRecord
autoload :Schema, 'hiddenrecord/schema'
autoload :Models, 'hiddenrecord/models'
...
end
require 'hiddenrecord/models/hideable'
require 'hiddenrecord/models/tracks_hidden_timestamp'
Anche in questo caso, riconoscendo che questo è soprattutto un esperienza di apprendimento, spero che qualcuno possa indicarmi la giusta direzione su come farlo. Lo sto provando su Rails 3.
Per inciso, se si sta utilizzando questo per ASCIUGARE il codice nelle migrazioni, potrebbe segnalare un odore di codice perché si stanno ripetendo i campi nel modello di dati.Potrebbe indicare che è necessario normalizzare il modello di dati per ridurre la duplicazione. – BlueFish