Ruby on Rails 5.0升级无法使用rails console或db:migrate

在最近从4.2升级到Ruby on Rails 5.0之后,我无法运行rake db:migrate或rails console。 我认为最好首先解决控制台错误,它似乎给了以下更多信息错误:

如果我正确理解您的请求,这是完整的堆栈跟踪。 谢谢。

$ rails c /Users/my_username/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0/lib/action_controller/test_case.rb:49:in `initialize': wrong number of arguments (given 0, expected 2) (ArgumentError) from /Users/my_username/.rvm/gems/ruby-2.3.0/bundler/gems/draper-57a514133bc2/lib/draper/view_context/build_strategy.rb:41:in `new' from /Users/my_username/.rvm/gems/ruby-2.3.0/bundler/gems/draper-57a514133bc2/lib/draper/view_context/build_strategy.rb:41:in `block in controller' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/andand-1.3.3/lib/andand.rb:60:in `me' from /Users/my_username/.rvm/gems/ruby-2.3.0/bundler/gems/draper-57a514133bc2/lib/draper/view_context/build_strategy.rb:40:in `controller' from /Users/my_username/.rvm/gems/ruby-2.3.0/bundler/gems/draper-57a514133bc2/lib/draper/view_context/build_strategy.rb:30:in `call' from /Users/my_username/.rvm/gems/ruby-2.3.0/bundler/gems/draper-57a514133bc2/lib/draper/view_context.rb:49:in `build' from /Users/my_username/.rvm/gems/ruby-2.3.0/bundler/gems/draper-57a514133bc2/lib/draper/railtie.rb:63:in `block in ' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/railtie.rb:226:in `block in run_console_blocks' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/railtie.rb:247:in `each' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/railtie.rb:247:in `each_registered_block' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/railtie.rb:226:in `run_console_blocks' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/application.rb:463:in `block in run_console_blocks' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/engine/railties.rb:13:in `each' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/engine/railties.rb:13:in `each' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/application.rb:463:in `run_console_blocks' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/engine.rb:442:in `load_console' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0/lib/rails/commands/console.rb:34:in `initialize' from /Users/my_username/.rvm/gems/ruby-2.3.0/gems/railties- --clipped 441 characters to enter stack overflow question edit 

据我所知,actionpack-5.0.0 gem的test_case.rb部分需要两个参数。 在Textmate中打开此代码后,我看到’initialize’方法是以下test_case.rb文件中TestRequest类的一部分:

 require 'rack/session/abstract/id' require 'active_support/core_ext/hash/conversions' require 'active_support/core_ext/object/to_query' require 'active_support/core_ext/module/anonymous' require 'active_support/core_ext/hash/keys' require 'action_controller/template_assertions' require 'rails-dom-testing' module ActionController # :stopdoc: class Metal include Testing::Functional end module Live # Disable controller / rendering threads in tests. User tests can access # the database on the main thread, so they could open a txn, then the # controller thread will open a new connection and try to access data # that's only visible to the main thread's txn. This is the problem in #23483 remove_method :new_controller_thread def new_controller_thread # :nodoc: yield end end # ActionController::TestCase will be deprecated and moved to a gem in Rails 5.1. # Please use ActionDispatch::IntegrationTest going forward. class TestRequest (_) { non_path_parameters } data = non_path_parameters.to_query end end set_header 'CONTENT_LENGTH', data.length.to_s set_header 'rack.input', StringIO.new(data) end fetch_header("PATH_INFO") do |k| set_header k, generated_path end path_parameters[:controller] = controller_path path_parameters[:action] = action self.path_parameters = path_parameters end ENCODER = Class.new do include Rack::Test::Utils def should_multipart?(params) # FIXME: lifted from Rack-Test. We should push this separation upstream multipart = false query = lambda { |value| case value when Array value.each(&query) when Hash value.values.each(&query) when Rack::Test::UploadedFile multipart = true end } params.values.each(&query) multipart end public :build_multipart def content_type "multipart/form-data; boundary=#{Rack::Test::MULTIPART_BOUNDARY}" end end.new private def params_parsers super.merge @custom_param_parsers end end class LiveTestResponse < Live::Response # Was the response successful? alias_method :success?, :successful? # Was the URL not found? alias_method :missing?, :not_found? # Was there a server-side error? alias_method :error?, :server_error? end # Methods #destroy and #load! are overridden to avoid calling methods on the # @store object, which does not exist for the TestSession class. class TestSession < Rack::Session::Abstract::SessionHash #:nodoc: DEFAULT_OPTIONS = Rack::Session::Abstract::Persisted::DEFAULT_OPTIONS def initialize(session = {}) super(nil, nil) @id = SecureRandom.hex(16) @data = stringify_keys(session) @loaded = true end def exists? true end def keys @data.keys end def values @data.values end def destroy clear end def fetch(key, *args, &block) @data.fetch(key.to_s, *args, &block) end private def load! @id end end # Superclass for ActionController functional tests. Functional tests allow you to # test a single controller action per test method. This should not be confused with # integration tests (see ActionDispatch::IntegrationTest), which are more like # "stories" that can involve multiple controllers and multiple actions (ie multiple # different HTTP requests). # # == Basic example # # Functional tests are written as follows: # 1. First, one uses the +get+, +post+, +patch+, +put+, +delete+ or +head+ method to simulate # an HTTP request. # 2. Then, one asserts whether the current state is as expected. "State" can be anything: # the controller's HTTP response, the database contents, etc. # # For example: # # class BooksControllerTest < ActionController::TestCase # def test_create # # Simulate a POST response with the given HTTP parameters. # post(:create, params: { book: { title: "Love Hina" }}) # # # Asserts that the controller tried to redirect us to # # the created book's URI. # assert_response :found # # # Asserts that the controller really put the book in the database. # assert_not_nil Book.find_by(title: "Love Hina") # end # end # # You can also send a real document in the simulated HTTP request. # # def test_create # json = {book: { title: "Love Hina" }}.to_json # post :create, json # end # # == Special instance variables # # ActionController::TestCase will also automatically provide the following instance # variables for use in the tests: # # @controller:: # The controller instance that will be tested. # @request:: # An ActionController::TestRequest, representing the current HTTP # request. You can modify this object before sending the HTTP request. For example, # you might want to set some session properties before sending a GET request. # @response:: # An ActionDispatch::TestResponse object, representing the response # of the last HTTP response. In the above example, @response becomes valid # after calling +post+. If the various assert methods are not sufficient, then you # may use this object to inspect the HTTP response in detail. # # (Earlier versions of \Rails required each functional test to subclass # Test::Unit::TestCase and define @controller, @request, @response in +setup+.) # # == Controller is automatically inferred # # ActionController::TestCase will automatically infer the controller under test # from the test class name. If the controller cannot be inferred from the test # class name, you can explicitly set it with +tests+. # # class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase # tests WidgetController # end # # == \Testing controller internals # # In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions # can be used against. These collections are: # # * session: Objects being saved in the session. # * flash: The flash objects currently in the session. # * cookies: \Cookies being sent to the user on this request. # # These collections can be used just like any other hash: # # assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave" # assert flash.empty? # makes sure that there's nothing in the flash # # On top of the collections, you have the complete url that a given action redirected to available in redirect_to_url. # # For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another # action call which can then be asserted against. # # == Manipulating session and cookie variables # # Sometimes you need to set up the session and cookie variables for a test. # To do this just assign a value to the session or cookie collection: # # session[:key] = "value" # cookies[:key] = "value" # # To clear the cookies for a test just clear the cookie collection: # # cookies.clear # # == \Testing named routes # # If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case. # # assert_redirected_to page_url(title: 'foo') class TestCase < ActiveSupport::TestCase module Behavior extend ActiveSupport::Concern include ActionDispatch::TestProcess include ActiveSupport::Testing::ConstantLookup include Rails::Dom::Testing::Assertions attr_reader :response, :request module ClassMethods # Sets the controller class name. Useful if the name can't be inferred from test class. # Normalizes +controller_class+ before using. # # tests WidgetController # tests :widget # tests 'widget' def tests(controller_class) case controller_class when String, Symbol self.controller_class = "#{controller_class.to_s.camelize}Controller".constantize when Class self.controller_class = controller_class else raise ArgumentError, "controller class must be a String, Symbol, or Class" end end def controller_class=(new_class) self._controller_class = new_class end def controller_class if current_controller_class = self._controller_class current_controller_class else self.controller_class = determine_default_controller_class(name) end end def determine_default_controller_class(name) determine_constant_from_test_name(name) do |constant| Class === constant && constant < ActionController::Metal end end end # Simulate a GET request with the given parameters. # # - +action+: The controller action to call. # - +params+: The hash with HTTP parameters that you want to pass. This may be +nil+. # - +body+: The request body with a string that is appropriately encoded # (application/x-www-form-urlencoded or multipart/form-data). # - +session+: A hash of parameters to store in the session. This may be +nil+. # - +flash+: A hash of parameters to store in the flash. This may be +nil+. # # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with # +post+, +patch+, +put+, +delete+, and +head+. # Example sending parameters, session and setting a flash message: # # get :show, # params: { id: 7 }, # session: { user_id: 1 }, # flash: { notice: 'This is flash message' } # # Note that the request method is not verified. The different methods are # available to make the tests more expressive. def get(action, *args) res = process_with_kwargs("GET", action, *args) cookies.update res.cookies res end # Simulate a POST request with the given parameters and set/volley the response. # See +get+ for more details. def post(action, *args) process_with_kwargs("POST", action, *args) end # Simulate a PATCH request with the given parameters and set/volley the response. # See +get+ for more details. def patch(action, *args) process_with_kwargs("PATCH", action, *args) end # Simulate a PUT request with the given parameters and set/volley the response. # See +get+ for more details. def put(action, *args) process_with_kwargs("PUT", action, *args) end # Simulate a DELETE request with the given parameters and set/volley the response. # See +get+ for more details. def delete(action, *args) process_with_kwargs("DELETE", action, *args) end # Simulate a HEAD request with the given parameters and set/volley the response. # See +get+ for more details. def head(action, *args) process_with_kwargs("HEAD", action, *args) end def xml_http_request(*args) ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc) xhr and xml_http_request methods are deprecated in favor of `get :index, xhr: true` and `post :create, xhr: true` MSG @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' @request.env['HTTP_ACCEPT'] ||= [Mime[:js], Mime[:html], Mime[:xml], 'text/xml', '*/*'].join(', ') __send__(*args).tap do @request.env.delete 'HTTP_X_REQUESTED_WITH' @request.env.delete 'HTTP_ACCEPT' end end alias xhr :xml_http_request # Simulate an HTTP request to +action+ by specifying request method, # parameters and set/volley the response. # # - +action+: The controller action to call. # - +method+: Request method used to send the HTTP request. Possible values # are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+. Can be a symbol. # - +params+: The hash with HTTP parameters that you want to pass. This may be +nil+. # - +body+: The request body with a string that is appropriately encoded # (application/x-www-form-urlencoded or multipart/form-data). # - +session+: A hash of parameters to store in the session. This may be +nil+. # - +flash+: A hash of parameters to store in the flash. This may be +nil+. # - +format+: Request format. Defaults to +nil+. Can be string or symbol. # # Example calling +create+ action and sending two params: # # process :create, # method: 'POST', # params: { # user: { name: 'Gaurish Sharma', email: 'user@example.com' } # }, # session: { user_id: 1 }, # flash: { notice: 'This is flash message' } # # To simulate +GET+, +POST+, +PATCH+, +PUT+, +DELETE+ and +HEAD+ requests # prefer using #get, #post, #patch, #put, #delete and #head methods # respectively which will make tests more expressive. # # Note that the request method is not verified. def process(action, *args) check_required_ivars if kwarg_request?(args) parameters, session, body, flash, http_method, format, xhr = args[0].values_at(:params, :session, :body, :flash, :method, :format, :xhr) else http_method, parameters, session, flash = args format = nil if parameters.is_a?(String) && http_method != 'HEAD' body = parameters parameters = nil end if parameters || session || flash non_kwarg_request_warning end end if body @request.set_header 'RAW_POST_DATA', body end if http_method http_method = http_method.to_s.upcase else http_method = "GET" end parameters ||= {} if format parameters[:format] = format end @html_document = nil self.cookies.update @request.cookies self.cookies.update_cookies_from_jar @request.set_header 'HTTP_COOKIE', cookies.to_header @request.delete_header 'action_dispatch.cookies' @request = TestRequest.new scrub_env!(@request.env, @request.session) @response = build_response @response_klass @response.request = @request @controller.recycle! @request.set_header 'REQUEST_METHOD', http_method parameters = parameters.symbolize_keys generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action.to_s)) generated_path = generated_path(generated_extras) query_string_keys = query_parameter_names(generated_extras) @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters, generated_path, query_string_keys) @request.session.update(session) if session @request.flash.update(flash || {}) if xhr @request.set_header 'HTTP_X_REQUESTED_WITH', 'XMLHttpRequest' @request.fetch_header('HTTP_ACCEPT') do |k| @request.set_header k, [Mime[:js], Mime[:html], Mime[:xml], 'text/xml', '*/*'].join(', ') end end @request.fetch_header("SCRIPT_NAME") do |k| @request.set_header k, @controller.config.relative_url_root end begin @controller.recycle! @controller.dispatch(action, @request, @response) ensure @request = @controller.request @response = @controller.response @request.delete_header 'HTTP_COOKIE' if @request.have_cookie_jar? unless @request.cookie_jar.committed? @request.cookie_jar.write(@response) self.cookies.update(@request.cookie_jar.instance_variable_get(:@cookies)) end end @response.prepare! if flash_value = @request.flash.to_session_value @request.session['flash'] = flash_value else @request.session.delete('flash') end if xhr @request.delete_header 'HTTP_X_REQUESTED_WITH' @request.delete_header 'HTTP_ACCEPT' end @request.query_string = '' @response.sent! end @response end def controller_class_name @controller.class.anonymous? ? "anonymous" : @controller.class.controller_path end def generated_path(generated_extras) generated_extras[0] end def query_parameter_names(generated_extras) generated_extras[1] + [:controller, :action] end def setup_controller_request_and_response @controller = nil unless defined? @controller @response_klass = ActionDispatch::TestResponse if klass = self.class.controller_class if klass < ActionController::Live @response_klass = LiveTestResponse end unless @controller begin @controller = klass.new rescue warn "could not construct controller #{klass}" if $VERBOSE end end end @request = TestRequest.create @response = build_response @response_klass @response.request = @request if @controller @controller.request = @request @controller.params = {} end end def build_response(klass) klass.create end included do include ActionController::TemplateAssertions include ActionDispatch::Assertions class_attribute :_controller_class setup :setup_controller_request_and_response end private def scrub_env!(env) env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ } env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ } env.delete 'action_dispatch.request.query_parameters' env.delete 'action_dispatch.request.request_parameters' env end def process_with_kwargs(http_method, action, *args) if kwarg_request?(args) args.first.merge!(method: http_method) process(action, *args) else non_kwarg_request_warning if args.any? args = args.unshift(http_method) process(action, *args) end end REQUEST_KWARGS = %i(params session flash method body xhr) def kwarg_request?(args) args[0].respond_to?(:keys) && ( (args[0].key?(:format) && args[0].keys.size == 1) || args[0].keys.any? { |k| REQUEST_KWARGS.include?(k) } ) end def non_kwarg_request_warning ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc) ActionController::TestCase HTTP request methods will accept only keyword arguments in future Rails versions. Examples: get :show, params: { id: 1 }, session: { user_id: 1 } process :update, method: :post, params: { id: 1 } MSG end def document_root_element html_document.root end def check_required_ivars # Sanity check for required instance variables so we can give an # understandable error message. [:@routes, :@controller, :@request, :@response].each do |iv_name| if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil? raise "#{iv_name} is nil: make sure you set it in your test's setup method." end end end def html_format?(parameters) return true unless parameters.key?(:format) Mime.fetch(parameters[:format]) { Mime['html'] }.html? end end include Behavior end # :startdoc: end 

运行rake db:migrate时出现错误:

耙子流产了! NameError:未初始化的常量ActiveSupport /Users/my_username/projects/zoner/config/application.rb:1:in`

这是application.rb文件的第一行:

 ActiveSupport.halt_callback_chains_on_return_false = false require File.expand_path('../boot', __FILE__) require File.expand_path('../initializers/decent_exposure', __FILE__) require 'rails/all' require 'active_support' require 'active_support/core_ext' 

如果有人可以帮助识别此代码中的错误,这将帮助我向TestRequest类添加必要的参数,这将非常有用。 谢谢。

来自@ scott-w的更新 (2016年8月):

现在正确的位置: gem 'draper', github: 'drapergem/draper'

rails-5分支已合并为master并且不再存在

原文 :rails控制台错误的问题是由跟踪器中的draper gem引起的。 现在看来,draper的主(主)分支不支持Rails 5.它似乎已经知道了很长一段时间,但在Rails 5正式发布之前稳定,它并没有真正开始行动。

尝试嵌入一些修复程序的这个fork(“旧”解决方案)

 gem 'draper', github: 'audionerd/draper', branch: 'rails5' 

从这里开始

或者更好(似乎成为当前的解决方案)

 gem 'draper', github: 'drapergem/draper', branch: 'rails-5' 

这种官方分支的工作正如我们所说的那样:) https://github.com/drapergem/draper/commits/rails-5

或者为Rails 5删除draper,因为它在它的主分支中还不支持它(在未来几天似乎会改变)

更新 – > rails-5分支已合并为master,因此现在支持Rails 5