Custom Ruby on Rails Migration Generator

I am creating a Rails Stone that integrates closely with Active Record. A gem requires a certain number of fields. For example:

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

Is it possible to have something like:

 rails g model user name:string avatar:attached 

Result:

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

If this is not possible, any way to do:

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

Create multiple fields? Thanks!

+4
ruby-on-rails gem
source share
3 answers

While Pravin pointed in the right direction, I found that it was not easy to realize. I did the following: I added a file to config/initializers (the name does not matter) containing the following:

 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 

then you can just do something like:

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

which will create the following migration:

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

If you start the migration, rake db:migrate , it will create the following Person model:

 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) 

Hope this helps!

+3
source share

Actually, if you call

 rails g model profile name:string next:attached 

rails allready generates you a migration using

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

however, you can override the default migration template by placing it in / lib / templates / active _record / model / migration.rb

You should write the rake my_gem: setup command to put the file there. I have not tried it, but I think the rails are not looking in non-motor gems for these patterns

The contents of your migration template will look like this:

 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 
+3
source share

I view t.attached similar t.attached to t.references in a polymorphic association.

As for the references method, you can have something like below

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

You may like the extension ActiveRecord::ConnectionAdapters::TableDefinition
Take a look at this http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#method-i-references

+2
source share

All Articles