2016-10-13 5 views
0

레일즈 생성기 워크 플로에 대해 오해 할 것입니다. 그러나 며칠 동안 코드와 문서를 검색 한 결과, 문제.Rails 5 generator db : 롤백은 마이그레이션 파일을 삭제하기 전에 호출되지만 아무것도 수행하지 않습니다.

일부 추가 파일을 추가하고 스캐 폴드 파일을 만든 직후 생성 된 마이 그 레이션을 실행하기 위해 사용자 정의 스카 폴드 생성기를 만들었습니다. 동일한 방법으로 나는 처음으로 마이그레이션을 롤백하려고합니다. rails destroy my_scaffold 명령이 실행되어 마이그레이션 파일이 삭제되기 전에 롤백됩니다.

내 맞춤 생성기 코드 scaffold_meta.rb, 마이 그 레이션 파일을 만든 후 db : migrate 명령을 실행합니다. 이것은 작동하는 부분입니다.

require 'generators/resource/resource_generator' 
module Rails 
    module Generators 
    class ScaffoldMetaGenerator < ResourceGenerator # :nodoc: 
     remove_hook_for :resource_controller 
     remove_class_option :actions 

     class_option :stylesheets, type: :boolean, desc: "Generate Stylesheets" 
     class_option :stylesheet_engine, desc: "Engine for Stylesheets" 
     class_option :assets, type: :boolean 
     class_option :resource_route, type: :boolean 
     class_option :scaffold_stylesheet, type: :boolean 
     class_option :steps, type: :boolean, default: 'step' 

     def handle_skip 
     @options = @options.merge(stylesheets: false) unless options[:assets] 
     @options = @options.merge(stylesheet_engine: false) unless options[:stylesheets] && options[:scaffold_stylesheet] 
     end 

     hook_for :scaffold_controller, required: true 

     hook_for :assets do |assets| 
     invoke assets, [controller_name] 
     end 

     hook_for :stylesheet_engine do |stylesheet_engine| 
     if behavior == :invoke 
      invoke stylesheet_engine, [controller_name] 
     end 
     end 

     def mirate_if_invoke 
     if behavior == :invoke 
      say behavior.to_s + ' migrate', :green 
      rake("db:migrate --trace") 
     end 
     end 

     invoke 'step' 

    end 
    end 
end 

앞의 코드는 내 사용자 지정 마이그레이션 파일을 삭제하기 전에 롤백을 시도 model_generator.rb를 호출 끝납니다. 롤백 suposedly라고하지만 효과가 없습니다 : REVOKE 행동 발전기의

require 'rails/generators/model_helpers' 

module Rails 
    module Generators 
    class ModelGenerator < Rails::Generators::NamedBase # :nodoc: 
     include Rails::Generators::ModelHelpers 

     def rollback_if_revoke 
     if self.behavior == :revoke 
      say behavior.to_s + ' rollback', :red 
      rake("db:rollback --trace") 
     end 
     end 

     argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]" 
     hook_for :orm, required: true, desc: "ORM to be invoked" 
    end 
    end 
end 

출력은 레이크 데시벨이 방법을 보여줍니다.

$rails d scaffold_meta pez edad:integer nombre 

Running via Spring preloader in process 8888 

***revoke rollback 

    rake db:rollback --trace*** 
    invoke active_record 
    remove db/migrate/20161013145014_create_pezs.rb 
    remove app/models/pez.rb 
    invoke rspec` 

매우 도움이 될만한 도움이 될 것입니다.

답변

0

Rails 4.7.0에서 같은 문제가 발생했습니다.

내가 일 때 behavior == :invoke이 작동했지만 아무 것도하지 않았을 때 나타났습니다. behavior == :revoke. rake 방법 소스 찾고

:

in_root로 전달 블록 불리는 run 방법은 Thor::Actions 모듈 내지
# GEMDIR/railties-4.2.7/lib/rails/generators/actions.rb: 

    # Runs the supplied rake task 
    # 
    # rake("db:migrate") 
    # rake("db:migrate", env: "production") 
    # rake("gems:install", sudo: true) 
    def rake(command, options={}) 
    log :rake, command 
    env = options[:env] || ENV["RAILS_ENV"] || 'development' 
    sudo = options[:sudo] && RbConfig::CONFIG['host_os'] !~ /mswin|mingw/ ? 'sudo ' : '' 
    in_root { run("#{sudo}#{extify(:rake)} #{command} RAILS_ENV=#{env}", verbose: false) } 
    end 

:

# GEMDIR/thor-0.19.1/lib/thor/actions.rb: 

# Executes a command returning the contents of the command. 
# 
# ==== Parameters 
# command<String>:: the command to be executed. 
# config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output. Specify :with 
#    to append an executable to command execution. 
# 
# ==== Example 
# 
# inside('vendor') do 
#  run('ln -s ~/edge rails') 
# end 
# 
def run(command, config = {}) 
    return unless behavior == :invoke 

    destination = relative_to_original_destination_root(destination_root, false) 
    desc = "#{command} from #{destination.inspect}" 

    if config[:with] 
    desc = "#{File.basename(config[:with].to_s)} #{desc}" 
    command = "#{config[:with]} #{command}" 
    end 

    say_status :run, desc, config.fetch(:verbose, true) 

    unless options[:pretend] 
    config[:capture] ? `#{command}` : system("#{command}") 
    end 
end 

방법의 첫 번째 라인 return unless behavior == :invoke 짧은 원래 rake 'db:rollback' 명령을 실행하는 호출을 회선합니다.

철선은 또한 \ revoke 로직을 따르는 것으로 보이는 Actions 모듈 (Rails::Generators::Actions)을 가지고 있습니다. 그래서 발전기가 :revoke 상태 일 때 롤백을 시도하지 않는 것이 가장 좋습니다.

내가 :invoke에 마이그레이션 파일을 생성하고, :revoke에 그것을 파괴하고 필요한 경우 수동으로 rake db:migrate 또는 rake db:rollback을 실행하는 사용자에 의존하는 레일 규칙을 다음 결국했습니다.

희망이 있습니다.