web-dev-qa-db-ja.com

複数のファイルを介した大規模プロジェクトでのシナトラの使用

シナトラでは、すべてのルートハンドラが単一のファイルに書き込まれているようです。もし理解できれば、1つの大小のコントローラとして機能します。それを別々の独立したファイルに分割する方法はありますか?誰かが「/」を呼び出すと言うと-1つのアクションが実行され、「/ posts/2」のようなsmthが受信されると別のアクション-PHPで適用される同様のロジック?

183
spacemonkey

私が使用するSinatraアプリの基本的なテンプレートを次に示します。 (私の大規模なアプリには、ベンダーの宝石をカウントせずに75以上の明示的なルートをカバーする200以上のファイルがあります。これらのルートの一部は、追加の50以上のルートパターンをカバーするRegexpルートです。)次のようなアプリ:
thin -R config.ru start

Edit:私は今、自分自身を維持しています Monk 以下に基づいたスケルトン- リブリッツ。それを使用して、自分のプロジェクトのベースとしてテンプレートをコピーするには:

# Before creating your project
monk add riblits git://github.com/Phrogz/riblits.git

# Inside your empty project directory
monk init -s riblits

ファイルレイアウト:

 config.ru 
 app.rb 
 helpers /
 init.rb 
 partials.rb 
 models /
 init.rb 
 user.rb 
 routes /
 init.rb 
 login.rb 
 main.rb 
 views/
 layout.haml 
 login.haml 
 main.haml 


config.ru

root = ::File.dirname(__FILE__)
require ::File.join( root, 'app' )
run MyApp.new


app.rb

# encoding: utf-8
require 'sinatra'
require 'haml'

class MyApp < Sinatra::Application
  enable :sessions

  configure :production do
    set :haml, { :ugly=>true }
    set :clean_trace, true
  end

  configure :development do
    # ...
  end

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

require_relative 'models/init'
require_relative 'helpers/init'
require_relative 'routes/init'


helpers/init.rb

# encoding: utf-8
require_relative 'partials'
MyApp.helpers PartialPartials

require_relative 'nicebytes'
MyApp.helpers NiceBytes


helpers/partials.rb

# encoding: utf-8
module PartialPartials
  def spoof_request(uri,env_modifications={})
    call(env.merge("PATH_INFO" => uri).merge(env_modifications)).last.join
  end

  def partial( page, variables={} )
    haml page, {layout:false}, variables
  end
end


helpers/nicebytes.rb

# encoding: utf-8
module NiceBytes
  K = 2.0**10
  M = 2.0**20
  G = 2.0**30
  T = 2.0**40
  def Nice_bytes( bytes, max_digits=3 )
    value, suffix, precision = case bytes
      when 0...K
        [ bytes, 'B', 0 ]
      else
        value, suffix = case bytes
          when K...M then [ bytes / K, 'kiB' ]
          when M...G then [ bytes / M, 'MiB' ]
          when G...T then [ bytes / G, 'GiB' ]
          else            [ bytes / T, 'TiB' ]
        end
        used_digits = case value
          when   0...10   then 1
          when  10...100  then 2
          when 100...1000 then 3
          else 4
        end
        leftover_digits = max_digits - used_digits
        [ value, suffix, leftover_digits > 0 ? leftover_digits : 0 ]
    end
    "%.#{precision}f#{suffix}" % value
  end
  module_function :Nice_bytes  # Allow NiceBytes.Nice_bytes outside of Sinatra
end


models/init.rb

# encoding: utf-8
require 'sequel'
DB = Sequel.postgres 'dbname', user:'bduser', password:'dbpass', Host:'localhost'
DB << "SET CLIENT_ENCODING TO 'UTF8';"

require_relative 'users'


models/user.rb

# encoding: utf-8
class User < Sequel::Model
  # ...
end


routes/init.rb

# encoding: utf-8
require_relative 'login'
require_relative 'main'


routes/login.rb

# encoding: utf-8
class MyApp < Sinatra::Application
  get "/login" do
    @title  = "Login"
    haml :login
  end

  post "/login" do
    # Define your own check_login
    if user = check_login
      session[ :user ] = user.pk
      redirect '/'
    else
      redirect '/login'
    end
  end

  get "/logout" do
    session[:user] = session[:pass] = nil
    redirect '/'
  end
end


routes/main.rb

# encoding: utf-8
class MyApp < Sinatra::Application
  get "/" do
    @title = "Welcome to MyApp"        
    haml :main
  end
end


views/layout.haml

!!! XML
!!! 1.1
%html(xmlns="http://www.w3.org/1999/xhtml")
  %head
    %title= @title
    %link(rel="icon" type="image/png" href="/favicon.png")
    %meta(http-equiv="X-UA-Compatible" content="IE=8")
    %meta(http-equiv="Content-Script-Type" content="text/javascript" )
    %meta(http-equiv="Content-Style-Type" content="text/css" )
    %meta(http-equiv="Content-Type" content="text/html; charset=utf-8" )
    %meta(http-equiv="expires" content="0" )
    %meta(name="author" content="MeWho")
  %body{id:@action}
    %h1= @title
    #content= yield
395
Phrogz

絶対に。この例を見るには、ここで説明するMonk gemをダウンロードすることをお勧めします。

https://github.com/monkrb/monk

Rubygems.orgから「gem install」できます。 gemを入手したら、上記のリンクの手順を使用してサンプルアプリを生成します。

実際に開発する場合、Monkを使用する必要がないことに注意してください(実際、Monkは最新ではないかもしれません)。重要なのは、必要に応じて、アプリをMVCスタイルで(個別のコントローラーのようなルートファイルを使用して)簡単に構成できる方法を確認することです。

Monkがどのように処理するかを見ると、それは非常に簡単です。ほとんどの場合、ファイルを別のディレクトリに配置する必要があります(root_pathを定義する必要があります)。

Dir[root_path("app/**/*.rb")].each do |file|
    require file
end
10
TK-421

Googleで「Sinatraボイラープレート」を検索して、他の人がSinatraアプリケーションをどのようにレイアウトしているかについていくつかのアイデアを見つけてください。それから、おそらくあなたのニーズに合ったものを見つけるか、単にあなた自身を作ることができます。難しいことではありません。 Sinatraアプリをさらに開発したら、定型文に追加できます。

すべてのプロジェクトで私が作成して使用したものは次のとおりです。

https://github.com/rziehl/sinatra-boilerplate

10
Robert Ziehl

私はこれが古いクエリであることを知っていますが、まだ誰も言及していないとは信じられません Padrino Sinatraのフレームワークとして、または興味のある宝石だけを少しずつ追加して使用できます。それは、お尻の10個のお尻を蹴ります!

7
Steven Garcia

モンクが私のために働かなかったとき、私は自分でテンプレートに取り組み始めました。

考えてみれば、一連のファイルを結び付けることについて特別なことはありません。修道士の哲学は、2011年の早い時期にRedDotRubyConfで説明され、特にメンテナンスがほとんど行われていないので、使用することは本当にオプションであると具体的に教えてくれました。

これはActiveRecordを使用したい人にとって良いスタートです。

シンプルシナトラMVC

https://github.com/katgironpe/simple-sinatra-mvc

1
kgpdeveloper

大規模プロジェクト向けのSinatraのモジュール性の鍵は、基礎となるツールの使用を学習することです。

SitePointには、非常に 良いチュートリアル があり、そこからモジュラーSinatraアプリとヘルパーを見ることができます。ただし、1つの重要な詳細に特別な注意を払う必要があります。 Rackupでは、複数のSinatraアプリを保持し、mountします。基本的なアプリの作成方法がわかったら、そのチュートリアルのconfig.ruファイルを見て、独立したSinatraアプリをマウントする方法を観察します。

RackでSinatraを実行することを学ぶと、モジュール性戦略のまったく新しい世界が開きます。これは明らかに、本当に便利なものを試してみることを勧めます。各サブアプリケーションに個別のGemsを使用することで、モジュールを簡単にバージョン管理できるようになります。

アプリにgemモジュールを使用する力を過小評価しないでください。十分に区切られた環境で実験的な変更を簡単にテストし、簡単に展開できます。何か問題が発生した場合に戻すことも同様に簡単です。

コードを整理する方法は数千ありますので、Railsに似たレイアウトを取得しようとしても問題ありません。ただし、独自の構造をカスタマイズする方法について 偉大な投稿 もあります。この投稿は、ほとんどのWeb開発者のその他の頻繁なニーズをカバーしています。

時間があれば、RubyベースのWebアプリケーションの共通基盤であるRackについてさらに学ぶことをお勧めします。作業方法に与える影響ははるかに少ないかもしれませんが、ほとんどの人が自分のアプリで行う特定のタスクは常にあり、Rackミドルウェアとしてより適しています。

1
SystematicFrank

ここでドキュメントを読む:

シナトラ拡張

Sinatraを使用すると、アプリケーションをRubyモジュールに分解でき、Sinatraの「register」メソッドまたは「helper」メソッドから次のようにプルできるようです。

helpers.rb

require 'sinatra/base'

module Sinatra
  module Sample
    module Helpers

      def require_logged_in()
        redirect('/login') unless session[:authenticated]
      end

    end
  end
end

routing/foos.rb

require 'sinatra/base'

module Sinatra
  module Sample
    module Routing
      module Foos

        def self.registered(app)           
          app.get '/foos/:id' do
            # invoke a helper
            require_logged_in

            # load a foo, or whatever
            erb :foos_view, :locals => { :foo => some_loaded_foo }
          end   
        end  

      end
    end     
  end
end

app.rb

#!/usr/bin/env Ruby

require 'sinatra'

require_relative 'routing/foos'

class SampleApp < Sinatra::Base

  helpers Sinatra::Sample::Helpers

  register Sinatra::Sample::Routing::Foos

end
1