質問

I'm new to the ruby world, and Sinatra for that matter, so I have no choice but to ask here about the error I keep getting.

I'm using a combination of Rack + Sinatra with Slim as template engine. I have my app.rb setup as this:

module Pulsr

class StylusHandler < Sinatra::Base
  set :views, File.dirname(__FILE__) + '/stylus'

  get '/css/styles.css' do
    stylus :styles
  end
end

class Application < Sinatra::Base

  register Sinatra::ConfigFile

  config_file './config/config.yml'

  use Pulsr::Api
  use Pulsr::Routes

  enable :logging, :dump_errors if Sinatra::Base.development?
  disable :method_override, :run

  set :public_folder, File.join(:root.to_s, 'static')
  set :views, File.join(:root.to_s, 'views')
  #set :static_cache_control, [:public, max_age: 60 * 60 * 24 * 365] if Sinatra::Base.production?

end

end

And the Pulsr::Api and Pulsr::Routes are in two different files in a subdirectory. The issue I have is that slim tries to render the template relative to the path of the routes file, which looks like this:

module Pulsr
class Routes < Sinatra::Base
  get '/*' do
    slim :index
  end
end

end

So, my folder structure looks something like this:

- config
  - config.yml
  ...
- controllers
  - routes.rb
- views
  - index.slim
- app.rb
- config.ru
- Gemfile
...

I get this error: No such file or directory @ rb_sysopen - /Users/rolandjitsu/Projects/Products/pulsr/controllers/views/index.slim where the template is actually placed with one level up in the views folder.

Before I had all the code in the app.rb file, and , normally, it worked, but now I am unsure how to fix this path issue.

役に立ちましたか?

解決

You have set up your Routes class as a separate Sinatra application from your main app, and this means it has its own settings that are not shared. The views folder for the Routes app is therefore the default for that app, which is the the views directory inside the controllers directory.

The simple way to fix it would be to specify the views directory in the Routes class.

module Pulsr
  class Routes < Sinatra::Base

    # add this line
    set :views, File.expand_path(File.join(__FILE__, '../../views'))

    get '/*' do
      slim :index
    end
end

You could also set the app_file to be the main app file, the views, root and public_folder settings will all then be set based on that.

It looks like you don’t actually intend to create several separate applications, but rather split up your single app into several files. A possibly better way to do that would be to use extensions. You can create a module containing routes that you can include in your main application, and they will use the same settings as the main app.

module Routes # N.B modle not class

  # in this method you can add routes to the main app
  def self.registered(app)

    # you need to use 'app.get', not plain 'get'
    app.get '/*' do
      slim :index
    end
  end
end

Then in your main app call register Routes instead of use Routes. This is slightly more work to set up, but gives you more flexibility.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top