gpt4 book ai didi

ruby-on-rails - 如何使用其他方法扩展 ActiveRecord::Migration?

转载 作者:数据小太阳 更新时间:2023-10-29 06:34:48 26 4
gpt4 key购买 nike

我正在创建一个 Ruby gem,并希望使用我自己的助手来扩展 ActiveRecord::Migration 以创建必要的列。 (这类似于 Devise 在为其各种身份验证策略创建迁移时所做的事情。)我意识到我添加的功能本身非常微不足道,并且可能有更好/更有效的方法来做到这一点 - 我正在尝试将其作为学习经验而不是实际应用的东西。我只是想了解如何做一些像在 Rails 中添加新的迁移功能这样具有侵入性的事情。

到目前为止,我已经成功构建到 gem 中并安装了,但是当我尝试运行如下迁移时:

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

...它没有说 hideable 没有定义。

我研究了 Devise 完成此操作的方式,我不得不承认我有点迷路,但我试图摸索它。我做了以下事情:

使用我添加的新模型扩展了 ActiveRecord,并创建了一种方法来根据我的新迁移方法应用架构更改

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

创建了一个类似于 Devise 的 schema.rb 的模式模块,它定义了我想在迁移中使用的方法并调用了一个方法来应用模式

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

为模型添加了支持新字段的方法

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

在 gem 的主模块中加载架构和模型文件

module HiddenRecord
autoload :Schema, 'hiddenrecord/schema'
autoload :Models, 'hiddenrecord/models'
...
end
require 'hiddenrecord/models/hideable'
require 'hiddenrecord/models/tracks_hidden_timestamp'

同样,认识到这主要是一种学习体验,我希望有人能为我指明正确的方向,告诉我如何做到这一点。我正在 Rails 3 上尝试这个。

最佳答案

以下是我如何使用 Rails 2 和 MySQL 为之前的项目添加自定义迁移字段。效果很好。

我不知道这在多大程度上符合您的确切需求,所以请随时问我问题。

我把这段代码放在 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

关于ruby-on-rails - 如何使用其他方法扩展 ActiveRecord::Migration?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4240231/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com