0

Ubuntu / Apache2/PassengerでSinatraアプリケーションを実行しています。

これは、ステージングサーバーで機能する単純なURL短縮サービスですが、古いデータベース(短縮URLを含む)をインポートすると、次のエラーがスローされ始めました。

undefined method `include?' for nil:NilClass
file: resource.rb location: block in attributes= line: 332

完全なバックトレースはここにあります:

/usr/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/resource.rb in block in attributes=
            if model.allowed_writer_methods.include?(setter = "#{name}=")
/usr/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/resource.rb in each
      attributes.each do |name, value|
/usr/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/resource.rb in attributes=
      attributes.each do |name, value|
/websites/sinatra/shortener/application.rb in block in <top (required)>
        ct.attributes   =   { 
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in call
            proc { |a,p| unbound_method.bind(a).call } ]
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in block in compile!
            proc { |a,p| unbound_method.bind(a).call } ]
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in []
            route_eval { block[*args] }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in block (3 levels) in route!
            route_eval { block[*args] }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in route_eval
      throw :halt, yield
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in block (2 levels) in route!
            route_eval { block[*args] }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in block in process_route
        block ? block[self, values] : yield(self, values)
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in catch
      catch(:pass) do
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in process_route
      catch(:pass) do
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in block in route!
          pass_block = process_route(pattern, keys, conditions) do |*args|
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in each
        routes.each do |pattern, keys, conditions, block|
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in route!
        routes.each do |pattern, keys, conditions, block|
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in dispatch!
      route!
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in block in call!
      invoke { dispatch! }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in block in invoke
      res = catch(:halt) { yield }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in catch
      res = catch(:halt) { yield }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in invoke
      res = catch(:halt) { yield }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in call!
      invoke { dispatch! }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in call
      dup.call!(env)
/usr/lib/ruby/gems/1.9.1/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb in call
        status, headers, body = @app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/rack-protection-1.2.0/lib/rack/protection/path_traversal.rb in call
        app.call env
/usr/lib/ruby/gems/1.9.1/gems/rack-protection-1.2.0/lib/rack/protection/json_csrf.rb in call
        status, headers, body = app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/rack-protection-1.2.0/lib/rack/protection/base.rb in call
        result or app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb in call
        status, headers, body = @app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/rack-1.4.1/lib/rack/logger.rb in call
      @app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/rack-1.4.1/lib/rack/commonlogger.rb in call
      status, header, body = @app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/rack-1.4.1/lib/rack/head.rb in call
    status, headers, body = @app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/rack-1.4.1/lib/rack/methodoverride.rb in call
      @app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/showexceptions.rb in call
      @app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in block in call
        synchronize { prototype.call(env) }
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in synchronize
          yield
/usr/lib/ruby/gems/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb in call
        synchronize { prototype.call(env) }
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/rack/request_handler.rb in process_request
            status, headers, body = @app.call(env)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_request_handler.rb in accept_and_process_next_request
                    process_request(headers, input_stream, connection, full_http_response)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_request_handler.rb in main_loop
                if !accept_and_process_next_request(socket_wrapper, channel, buffer)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/rack/application_spawner.rb in start_request_handler
            handler.main_loop
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/rack/application_spawner.rb in block in handle_spawn_application
                self.class.send(:start_request_handler, MessageChannel.new(b),
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/utils.rb in safe_fork
                        yield
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/rack/application_spawner.rb in handle_spawn_application
        safe_fork('application', true) do
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_server.rb in server_main_loop
                            __send__(@message_handlers[name], client, *args)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_server.rb in start_synchronously
                server_main_loop(password, server_socket)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_server.rb in start
                start_synchronously(@socket_filename, @password, server_socket, b)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/rack/application_spawner.rb in start
        super
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/spawn_manager.rb in block (2 levels) in spawn_rack_application
                    spawner.start
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_server_collection.rb in lookup_or_add
            server = yield
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/spawn_manager.rb in block in spawn_rack_application
                spawner = @spawners.lookup_or_add(key) do
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_server_collection.rb in block in synchronize
                yield
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_server_collection.rb in synchronize
        @lock.synchronize do
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/spawn_manager.rb in spawn_rack_application
            @spawners.synchronize do
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/spawn_manager.rb in spawn_application
            return spawn_rack_application(options)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/spawn_manager.rb in handle_spawn_application
            app_process = spawn_application(options)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_server.rb in server_main_loop
                            __send__(@message_handlers[name], client, *args)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/lib/phusion_passenger/abstract_server.rb in start_synchronously
                server_main_loop(password, server_socket)
/usr/lib/ruby/gems/1.9.1/gems/passenger-3.0.12/helper-scripts/passenger-spawn-server in <main>
    spawn_manager.start_synchronously(socket_filename, socket_password, server_socket, owner_socket)

メインのapplication.rbファイルは次のとおりです。

require 'rubygems'
require 'bundler/setup'
require 'sinatra'
require File.join(File.dirname(__FILE__), 'environment')

configure do
    set :views, "#{File.dirname(__FILE__)}/views"
end

configure :development do
    DataMapper.auto_upgrade!

    # very useful for debugging parameters sent via the console
    before do
      puts '[Params]'
      p params
    end

end

error do
    e   =   request.env['sinatra.error']
    Kernel.puts e.backtrace.join("\n")
    'Application error'
end

helpers do  
    include Rack::Utils  
    alias_method :h, :escape_html  

    def random_string(length)  
        rand(36**length).to_s(36)  
    end 

    def get_site_url(short_url)
        SiteConfig.url_base + short_url
    end

    def generate_short_url(long_url)
      @shortcode = random_string 5

    su = ShortURL.first_or_create(
            { :url => long_url  }, 
            {
              :short_url  =>  @shortcode,
              :created_at =>  Time.now,
              :updated_at =>  Time.now
            })

    get_site_url(su.short_url)
    end

end


# root page
get '/' do

    if params[:url] and not params[:url].empty?

        generate_short_url(params[:url])

    else
        # you can use this page to redirect to another location
        # or to display a front-end form for any site visitors

        # get the current count of all links stored
    # @urls = ShortURL.all;

    # erb :index

    end

end

post '/' do

  if params[:url] and not params[:url].empty?

    generate_short_url(params[:url])

  end
    # you can use this page to redirect to another location
    # or to display a front-end form for any site visitors

    # get the current count of all links stored
    # @urls = ShortURL.all;

    # erb :index

end


# display short url from root
["/get/:short_url", "/:short_url"].each do |path|
get path do
    @URLData = ShortURL.get(params[:short_url])

    if @URLData

        # log the click in the database     
        ct = ClickTrack.new
        ct.attributes   =   { 
                :short_url  =>  params[:short_url],
                :url        =>  @URLData.url,   
                :clicked_at =>  Time.now
            }
        ct.save

        redirect @URLData.url
    else
        'no short url found'
    end

end
end

# expand url data
get '/expand/:hash/?' do
    @URLData = ShortURL.get(params[:hash])  

    if @URLData

        content_type :json
        { :url => get_site_url(@URLData.short_url), :long_url => @URLData.url, :hash => params[:hash] }.to_json

    else

        content_type :json
        { :message => 'No hash parameter was specified or no short URL was found to match the provided hash' }.to_json

    end
end

短縮URLを返すときにエラーが発生しています(#ルートからの短縮URLを表示)

なぜ失敗するのかを誰かが理解するのを手伝ってくれるなら、本当にありがたいです。

どうもありがとう

4

1 に答える 1

9

秘訣はスタックトレースを読み取ることです。ClickTrackはDataMapperオブジェクトだと思いますが、あなたはそれを呼び出しattributes=ています。スタックトレースは、dm-core内から少しのコードを提供するのに十分親切です。 if model.allowed_writer_methods.include?(setter = "#{name}=")

明らかに、データマッパー内からmodel.allowed_writer_methodsはnilを返しています。私はデータマッパーをまったく使用していませんが、少しグーグルすると1つの可能性があります。

https://github.com/datamapper/dm-core/issues/152

http://datamapper.org/getting-started.htmlによると、モデルを使用する前に 電話する必要がDataMapper.finalizeあります。

とにかく、これはDataMapperの問題のように見えます。ClickTrackを見て、それが完成していることを確認するか(正しく読んでいる場合)、DataMapperの使用状況を確認してください。

于 2012-05-31T13:38:57.337 に答える