插件中的生成器和迁移(Rails 3)

10
我正在尝试创建一个插件迁移生成器,不带任何参数,例如:$rails generate yaffle,这应该将迁移文件(lib/generators/yaffle/template/create_yaffle.rb)复制到db/migrate/[timestamp]_create_yaffle.rb。
问题在于,它确实进行了复制,但没有时间戳。
此外,当我运行$rails generate yaffle时,它会给我一个消息,说没有提供参数,它期望的格式是rails generate yaffle NAME [options]。我不想有任何选项/参数,它应该只是rails generate yaffle
我该怎么办?
我遵循了acts_as_commentable中使用的生成器,看起来非常简单,但我不知道在哪里修改这些设置... 有人可以帮忙吗?
生成器代码:
require 'rails/generators'
require 'rails/generators/migration'

class ThumbitGenerator  Rails::Generators::NamedBase
  source_root File.expand_path('../templates', __FILE__)

  def self.next_migration_number(path)
    Time.now.utc.strftime("%Y%m%d%H%M%S")
  end

  def create_model_file
    template "like.rb", "app/models/like.rb"
    template "liking.rb", "app/models/liking.rb"
    template "create_likes.rb", "db/migrate/create_likes.rb"
    template "create_likings.rb", "db/migrate/create_likings.rb"
  end

end

你的插件可以链接起来,这样我们就可以测试它了吗? - rwilliams
嘿,我想通了(看答案)...我已经更新了我的帖子并添加了生成器代码... - Madhusudhan
3个回答

22

好的,我找到了答案...

  1. 在我的生成器文件中,我使用了Rails::Generators::NamedBase而不是Rails::Generators::Base!当你使用NamedBase时,它总是期望传递一个参数(这是初始化器的名称)

    Explanation : guides.rubyonrails.org/generators

  2. 由于我使用了template方法而不是migration_template,所以迁移文件没有产生任何迁移编号

    Explanation: Rails::Generators::Migration.migration_template

最终,这个方法奏效了!

require 'rails/generators'
require 'rails/generators/migration'

class ThumbitGenerator < Rails::Generators::Base
  include Rails::Generators::Migration
  source_root File.expand_path('../templates', __FILE__)

  def self.next_migration_number(path)
    Time.now.utc.strftime("%Y%m%d%H%M%S")
  end

  def create_model_file
    template "like.rb", "app/models/like.rb"
    template "liking.rb", "app/models/liking.rb"
    migration_template "create_likes.rb", "db/migrate/create_likes.rb"
    migration_template "create_likings.rb", "db/migrate/create_likings.rb"
  end
end

当我使用多个迁移并运行rake db:migrate时,会出现以下情况:多个迁移具有版本号20110413160337,这是有道理的,因为两个迁移都使用相同的时间戳创建。你遇到过这种情况吗? - Mike Farmer
2
@Mike Farmer:在strftime格式字符串后添加“%6N”以获取微秒,然后你就可以愉快地使用了。像这样:https://gist.github.com/1110373 - davemyron
4
你可以使用require 'rails/generators/active_record',然后使用ActiveRecord::Generators::Base.next_migration_number(path)获取下一个迁移文件的号码。 - NARKOZ
大家好,我想知道是否可以使用类似于rails generate yaffle:install这样的东西?谢谢。 - Moh
@NARKOZ,该迁移模板将创建重复的迁移版本。 - seoyoochan

3

对于解决方案的小修改——为了避免在迁移时定义时间戳,并未将生成器适应可能由 Rails 核心团队决定使用另一种时间戳方式(例如 SHA 哈希截短为 10 个字符),您可以像这样require 'rails/generators/active_record'extend ActiveRecord::Generators::Migration

require 'rails/generators'
require 'rails/generators/migration'
require 'rails/generators/active_record'

class ThumbitGenerator < Rails::Generators::Base
  include Rails::Generators::Migration
  extend ActiveRecord::Generators::Migration

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

  def create_model_file
    template "like.rb", "app/models/like.rb"
    template "liking.rb", "app/models/liking.rb"
    migration_template "create_likes.rb", "db/migrate/create_likes.rb"
    migration_template "create_likings.rb", "db/migrate/create_likings.rb"
  end
end

在Rails 4中,ActiveRecord::Generators::Migration已不再是一个模块,因此请改用:

require 'rails/generators'
require 'rails/generators/migration'
require 'rails/generators/active_record'

class ThumbitGenerator < Rails::Generators::Base
  include Rails::Generators::Migration
  # Implement the required interface for Rails::Generators::Migration
  def self.next_migration_number(dirname)
    ActiveRecord::Generators::Base.next_migration_number(dirname)
  end

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

  def create_model_file
    template "like.rb", "app/models/like.rb"
    template "liking.rb", "app/models/liking.rb"
    migration_template "create_likes.rb", "db/migrate/create_likes.rb"
    migration_template "create_likings.rb", "db/migrate/create_likings.rb"
  end
end

1
您只需继承自ActiveRecord::Generators::Base,一切都会正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接