Question

I asked this earlier but did not receive any useful answers, so I'm trying again...

I need to create a gem or engine that will add needed columns/attributes to an existing model in the main app. Similar to the way the devise gem can create a model with or append devise needed attributes to an existing model.

My thinking is that the gem needs an install script similar to rails generate devise:install that will create the migration needed.

Any links, tutorials or advice will be greatly appreciated.

Was it helpful?

Solution

So as @23tux suggested I continued to look through the devise gem code base and found the solution that I needed.

in lib/generators/{gem_name} I made a file called {gem_name}_generator and in it I was able to follow the pattern of https://github.com/plataformatec/devise/blob/master/lib/generators/devise/devise_generator.rb and create a migration to append to an existing model in an app.

require 'rails/generators/named_base'
require 'rails/generators/active_record'

module GemName
  module Generators
    class GemNameGenerator < ActiveRecord::Generators::Base

    include Rails::Generators::ResourceHelpers

    namespace "gem_name"

    desc "Creates GemName Migrations"

    source_root File.expand_path("../templates", __FILE__)

    def copy_migration
      migration_template "migration_existing.rb", "db/migrate/add_gem_name_to_#{plural_name.downcase}"
    end

      def migration_data
  <<RUBY
    ## Add active column to table
    t.datetime :started_trial, :default => Time.now, :after => :id
    t.boolean :active, :default => true, :after => :started_trial
    t.boolean :allowed_past_trial, :default => false, :after => :active
  RUBY
      end
    end
  end
end

class_name and plural_name are accessible because in the terminal I ran $ rails generate gem_name account

thus class_name = 'account' and plural_name = 'accounts'

migration_existing.rb is in lib/generators/{gem_name}/templates and has the following code:

class AddGemNameTo<%= plural_name.camelize %> < ActiveRecord::Migration
  def self.up
    change_table(:<%= plural_name %>) do |t|
<%= migration_data %>
    end
  end

  def self.down
    # By default, we don't want to make any assumption about how to roll back a migration when your
    # model already existed. Please edit below which fields you would like to remove in this migration.
    raise ActiveRecord::IrreversibleMigration
  end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top