update run remove rails migrations column ruby-on-rails ruby activerecord

ruby on rails - run - ¿Cómo extender ActiveRecord:: Migration con métodos adicionales?



ruby on rails run migrations (2)

Estoy creando una gema de 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 estoy agregando es bastante trivial en sí misma y probablemente haya formas mejores / más eficientes de hacer esto. Estoy intentando esto como un Experiencia de aprendizaje en lugar de 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.

Lo que tengo hasta ahora se convierte en una gema 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

... falla diciendo que no se puede definir lo que se puede ocultar.

He investigado la forma en que Devise ha hecho esto y tengo que admitir que estoy un poco perdido, pero he intentado buscarlo. He hecho lo siguiente:

Extended ActiveRecord con mis nuevas incorporaciones de modelo y creó un método para aplicar los cambios de esquema basados ​​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

Creé un módulo de esquema similar al esquema de Devise.rb que define los métodos que quiero usar 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ñadidos para que los modelos soporten 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

Cargue los archivos de esquema y 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 orientarme en la dirección correcta sobre cómo hacer esto. Estoy intentando esto en Rails 3.


Así es como agregué campos de migración personalizados con Rails 2 y MySQL para un proyecto anterior. Funciona genial.

No sé cuánto de esto se aplica a su necesidad exacta, así que no dude en hacerme preguntas.

Puse este código en Rails.root / lib / dbd_migration_helper.rb

module Ddb module MigrationHelper def self.included(base) # :nodoc: base.send(:include, InstanceMethods) end module InstanceMethods def active (column_name=:active) column(column_name, :boolean, :default=>true) end def email (column_name=:email) column(column_name, :string) end def latitude (column_name=:latitude) column(column_name, :float) end def longitude (column_name=:longitude) column(column_name, :float) end def position (column_name=:position) column(column_name, :integer) end end end end require ''activerecord'' if defined?(ActiveRecord::ConnectionAdapters::TableDefinition) ActiveRecord::ConnectionAdapters::TableDefinition.send(:include, Ddb::MigrationHelper) end


Nota rápida, estas líneas:

ActiveRecord::ConnectionAdapters::Table.send :include, HiddenRecord::Orm::ActiveRecord::Schema ActiveRecord::ConnectionAdapters::TableDefinition.send :include, HiddenRecord::Orm::ActiveRecord::Schema

No parece estar incluyendo el módulo correcto. Creo que deberían ser:

ActiveRecord::ConnectionAdapters::Table.send :include, HiddenRecord::Schema ActiveRecord::ConnectionAdapters::TableDefinition.send :include, HiddenRecord::Schema

pero entonces, tampoco parece tener #tracks_hidden_at definido en ninguna parte.