【问题标题】:Ruby on Rails Custom Migration GeneratorRuby on Rails 自定义迁移生成器
【发布时间】:2011-03-16 05:22:39
【问题描述】:

我正在创建一个与 Active Record 紧密集成的 Rails gem。 gem 需要定义许多字段。例如:

class User < ActiveRecord::Base
  # requires 'avatar_identifier', 'avatar_extension', 'avatar_size'
  has_attached :avatar
end

是否有可能有类似的东西:

rails g model user name:string avatar:attached

导致:

create_table :users do |t|
  t.string :name
  t.string :avatar_identifier
  t.string :avatar_extension
  t.integer :avatar_size
end

如果这是不可能的,任何方法:

create_table :users do |t|
  t.string :name
  t.attached :avatar
end

生成多个字段?谢谢!

【问题讨论】:

    标签: ruby-on-rails gem


    【解决方案1】:

    虽然 Pravin 确实指出了正确的方向,但我发现实施它并不简单。我做了以下,我在config/initializers 中添加了一个文件(名称不相关),包含以下内容:

    require 'active_support'
    require 'active_record'
    
    class YourApplication
      module SchemaDefinitions
    
        module ExtraMethod
          def attachment(*args)
            options = args.extract_options!
            args.each do |col|
              column("#{col}_identifier", :string, options)
              column("#{col}_extension", :string, options)
              column("#{col}_size", :integer, options)
            end
          end
        end
    
        def self.load!
          ::ActiveRecord::ConnectionAdapters::TableDefinition.class_eval { include YourApplication::SchemaDefinitions::ExtraMethod }
        end
    
      end
    end
    
    
    ActiveSupport.on_load :active_record do
      YourApplication::SchemaDefinitions.load!
    end
    

    那么你可以这样做:

    rails g model Person name:string title:string avatar:attachment
    

    这将创建以下迁移:

    def self.up
      create_table :people do |t|
        t.string :name
        t.string :title
        t.attachment :avatar
    
        t.timestamps
      end
    end
    

    如果您随后运行迁移,rake db:migrate 它将创建以下 Person 模型:

    ruby-1.9.2-p0 > Person
     => Person(id: integer, name: string, title: string, avatar_identifier: string, avatar_extension: string, avatar_size: integer, created_at: datetime, updated_at: datetime) 
    

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      其实如果你打电话

      rails g model profile name:string next:attached
      

      rails 已经为您生成迁移

      def self.up
        create_table :profiles do |t|
          t.string :name
          t.attached :next
      
          t.timestamps
        end
      end
      

      但是,您可以通过将默认迁移模板放置在 /lib/templates/active_record/model/migration.rb

      你应该写一个 rake my_gem:setup 任务来把文件放在那里 我没试过,但我猜 Rails 不会在非引擎 gem 中搜索这些模板

      您的迁移模板内容将如下所示

      class <%= migration_class_name %> < ActiveRecord::Migration
        def self.up
          create_table :<%= table_name %> do |t|
      <% for attribute in attributes -%>
        <% if attribute.type.to_s == "attached" %>
            t.string :<%= attribute.name %>_identifier
            t.string :<%= attribute.name %>_extension
            t.integer :<%= attribute.name %>_size
        <% else %>
            t.<%= attribute.type %> :<%= attribute.name %>
        <% end %>
      <% end -%>
      <% if options[:timestamps] %>
            t.timestamps
      <% end -%>
          end
        end
      
        def self.down
          drop_table :<%= table_name %>
        end
      end
      

      【讨论】:

      • 这是一个不错的替代方法,但只有在使用生成器时才有效。
      • 那么问题是“是否有可能有类似的东西:rails g 模型用户名:字符串头像:附加”。因此我想这是适用的,但我明白你的意思。
      【解决方案3】:

      我认为t.attached 类似于多态关联中的t.references

      参考references 方法,您可以得到类似下面的内容

      def attached(*args)
        options = args.extract_options!
        column(:avatar_identifier, :string, options)
        column(:avatar_extension, :string, options)
        column(:avatar_size, :integer, options)
      end
      

      您可能想扩展ActiveRecord::ConnectionAdapters::TableDefinition
      看看这个 http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#method-i-references

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-28
        • 1970-01-01
        • 2015-04-09
        • 2019-12-24
        • 2012-11-11
        • 1970-01-01
        • 2014-07-27
        相关资源
        最近更新 更多