कई फ़ाइलों के माध्यम से बड़ी परियोजनाओं के लिए सिनात्रा का उपयोग करना


184

ऐसा लगता है कि सिनात्रा में सभी मार्ग संचालकों को एक ही फाइल में लिखा जा रहा है, अगर मैं सही समझता हूं तो यह एक बड़े / छोटे नियंत्रक के रूप में कार्य करता है। क्या इसे अलग-अलग स्वतंत्र फ़ाइलों में विभाजित करने का कोई तरीका है, इसलिए जब हम कहते हैं कि कोई व्यक्ति कॉल करता है "/" ​​- एक क्रिया निष्पादित की जाती है, और यदि "/ पोस्ट / 2" जैसे smth प्राप्त होता है, तो एक और कार्रवाई - समान तर्क जो PHP में लागू होता है ?

जवाबों:


394

यहाँ सिनात्रा ऐप के लिए एक बुनियादी टेम्पलेट है जो मैं उपयोग करता हूं। (मेरे बड़े ऐप्स में इस तरह से 200+ फाइलें हैं, जो वेंडर के रत्नों की गिनती नहीं कर रहे हैं, 75-100 स्पष्ट मार्गों को कवर करते हैं। इनमें से कुछ मार्ग Regexp मार्ग हैं जो अतिरिक्त 50+ मार्ग पैटर्न को कवर करते हैं।) थिन का उपयोग करते समय, आप चलाते हैं। इस तरह का उपयोग कर एप्लिकेशन:
thin -R config.ru start

संपादित करें : अब मैं अपने स्वयं के भिक्षु कंकाल को बनाए रख रहा हूं , जिसे नीचे के भाई-बहनों के नाम से जाना जाता है । अपने प्रोजेक्ट के आधार के रूप में मेरे टेम्पलेट को कॉपी करने के लिए इसका उपयोग करने के लिए:

# 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
सहायकों /
  init.rb
  partials.rb
मॉडल/
  init.rb
  user.rb
मार्गों /
  init.rb
  login.rb
  main.rb
विचारों /
  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'

 
सहायकों / init.rb

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

require_relative 'nicebytes'
MyApp.helpers NiceBytes

 
सहायकों / 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

 
सहायकों / 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

 
मॉडल / 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'

 
मॉडल / user.rb

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

 
मार्गों / init.rb

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

 
मार्गों / 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

 
मार्गों / main.rb

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

 
विचारों / 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

11
के बारे में एक विशेष रूप से अच्छी बात यह ऊपर संरचना-विशेष रूप से डालने require "sequel"और DBमें प्रारंभ models/init.rb, और का उपयोग कर require_relativeसभी के लिए फ़ाइलों-है कि आप अपने में सीडी कर सकते हैं modelsनिर्देशिका, एक आईआरबी कंसोल और प्रकार को खोल require './init'और आप अपना पूरा डेटाबेस और मॉडल सेटअप इंटरैक्टिव अन्वेषण के लिए भरी हुई है ।
मेंढक

1
महान उदाहरण संरचना, मेरे जैसे सिनात्रा नोब के लिए एकदम सही, चीयर्स।
बैरी जॉर्डन

27
मैंने एक अलग दृष्टिकोण का उपयोग किया। सभी व्यावसायिक तर्क जैसे कि उपयोगकर्ताओं और सेवाओं को रूबी में कोड करें, बिना किसी 'पापात्रा' की आवश्यकता के। यह तर्क को अपने दम पर खड़ा करता है। तब मैं विभिन्न वर्गों के लिए जिम्मेदारियों को पूरा करने के लिए एक एकल ऐप फ़ाइल का उपयोग करता हूं, इसलिए प्रति रूट कोड की लगभग 3 पंक्तियाँ। विशिष्ट एप्लिकेशन में कई मार्ग नहीं हैं, इसलिए मेरी ऐप फ़ाइल वास्तव में लंबे समय तक नहीं है।
टॉम एंडरसन

1
क्या कई फाइलों में एक कक्षा को परिभाषित करना एक आम बात है? आप 'MyApp' को हर फाइल में बार-बार बदल रहे हैं। मैं माणिक के लिए नया हूं इसलिए यह मुझे अजीब लगता है। इसके पीछे क्या कारण है?
0xSina

5
@ 0xSina यह रूबी में असामान्य नहीं है। आप एक वर्ग को "परिभाषित" नहीं करते हैं, आप इसे "फिर से खोलते हैं"। उदाहरण के लिए, Arrayवर्ग को मुख्य पुस्तकालय द्वारा परिभाषित किया गया है, लेकिन आप बाद में "बंदरों" का उपयोग करके class Array; def some_awesome_method; endऔर एक) सभी पिछले सरणी कार्यक्षमता संरक्षित है, और b) सभी सरणी उदाहरणों को आपका नया कोड मिलेगा। रूबी में कक्षाएं सिर्फ ऑब्जेक्ट हैं, और किसी भी समय संवर्धित और बदली जा सकती हैं।
मेंढक

10

पूर्ण रूप से। इसका एक उदाहरण देखने के लिए मैं यहाँ वर्णित भिक्षु मणि को डाउनलोड करने की सलाह देता हूँ:

https://github.com/monkrb/monk

आप इसे rubygems.org के माध्यम से 'मणि स्थापित' कर सकते हैं। एक बार आपके पास मणि होने के बाद, ऊपर दिए गए निर्देशों का उपयोग करके एक नमूना एप्लिकेशन बनाएं।

ध्यान दें कि आपको अपने वास्तविक विकास के लिए भिक्षु का उपयोग करने की आवश्यकता नहीं है जब तक आप नहीं चाहते (वास्तव में मुझे लगता है कि यह वर्तमान नहीं हो सकता है)। मुद्दा यह है कि आप आसानी से अपने ऐप को एमवीसी स्टाइल (अलग कंट्रोलर जैसी रूट फाइल्स के साथ) में कैसे आसानी से देख सकते हैं।

यह बहुत आसान है यदि आप देखते हैं कि भिक्षु इसे कैसे संभालता है, ज्यादातर अलग-अलग निर्देशिकाओं में फ़ाइलों की आवश्यकता होती है, तो कुछ ऐसा है (आपको root_path को परिभाषित करना होगा):

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

7
एक स्पष्ट init.rbबनाम उपरोक्त का उपयोग करने के बारे में एक अच्छी बात यह है कि आप अन्योन्याश्रित फ़ाइलों के मामले में, लोडिंग के क्रम को नियंत्रित कर सकते हैं।
फ़रोज़

10

"सिनात्रा बॉयलरप्लेट" के लिए एक Google खोज करें कि कुछ लोग अपने सिनात्रा अनुप्रयोगों को कैसे निकाल रहे हैं, इसके लिए कुछ विचार प्राप्त करें। उस से आप संभवतः अपनी आवश्यकताओं के अनुरूप एक खोज सकते हैं या बस अपना बना सकते हैं। यह करना बहुत मुश्किल नहीं है। जैसा कि आप अधिक सिनात्रा ऐप विकसित करते हैं, आप अपने बॉयलरप्लेट में जोड़ सकते हैं।

यहाँ मैंने अपनी सभी परियोजनाओं के लिए जो बनाया और उपयोग किया है:

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


7

मुझे पता है कि यह एक पुरानी क्वेरी है, लेकिन मैं अभी भी विश्वास नहीं कर सकता कि कोई भी पडरिनो का उल्लेख नहीं करता है आप इसे सिनात्रा के शीर्ष पर एक फ्रेमवर्क के रूप में उपयोग कर सकते हैं, या केवल ब्याज वाले रत्नों को जोड़कर टुकड़ा कर सकते हैं। यह गधे के दस नितंबों को मारता है!


मैं सहमत हूं, आपको पादरिनो पर एक नज़र डालनी चाहिए, यह चट्टानों!
निकोपाएज

2

एक ही साइट पर विभिन्न परियोजनाओं की मेजबानी करने का मेरा तरीका sinatra/namespaceइस तरह से उपयोग करना है:

server.rb

require "sinatra"
require "sinatra/namespace"

if [ENV["LOGNAME"], ENV["USER"]] == [nil, "naki"]
    require "sinatra/reloader"
    register Sinatra::Reloader
    set :port, 8719
else
    set :environment, :production
end

for server in Dir.glob "server_*.rb"
    require_relative server
end

get "/" do
    "this route is useless"
end

server_someproject.rb

module SomeProject
    def self.foo bar
       ...
    end
    ...
end

namespace "/someproject" do
    set :views, settings.root
    get "" do
        redirect request.env["REQUEST_PATH"] + "/"
    end
    get "/" do
        haml :view_someproject
    end
    post "/foo" do
        ...
        SomeProject.foo ...
    end
end

view_someproject.haml

!!!
%html
    ...

मेरे द्वारा उपयोग किए जाने वाले उपप्रोजेक्ट के बारे में एक और विवरण उनके नाम, विवरण और मार्गों को किसी प्रकार के वैश्विक चर में जोड़ना था, जिसका उपयोग "/"एक गाइड होमपेज बनाने के लिए किया जाता है , लेकिन मेरे पास अभी स्निपेट नहीं है।


1

यहाँ डॉक्स पढ़ना:

सिनात्रा एक्सटेंशन

ऐसा प्रतीत होता है कि सिनात्रा आपको अपने आवेदन को रूबी मॉड्यूल में विघटित करने की अनुमति देता है, जिसे सिनात्रा "रजिस्टर" विधि या "हेल्पर्स" विधियों के माध्यम से खींचा जा सकता है, जैसे:

helpers.rb

require 'sinatra/base'

module Sinatra
  module Sample
    module Helpers

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

    end
  end
end

मार्ग / 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

जब भिक्षु ने मेरे लिए काम नहीं किया, तो मैंने खुद ही टेम्पलेट्स पर काम करना शुरू कर दिया।

यदि आप इसके बारे में सोचते हैं, तो फ़ाइलों का एक सेट बांधने के बारे में कुछ खास नहीं है। RedDotRubyConf के दौरान 2011 में मुझे भिक्षु दर्शन की शुरुआत में समझाया गया था और उन्होंने मुझे विशेष रूप से कहा था कि इसका उपयोग करने के लिए वास्तव में वैकल्पिक है कि अब शायद ही इसे बनाए रखा जाए।

यह उन लोगों के लिए एक अच्छी शुरुआत है जो ActiveRecord का उपयोग करना चाहते हैं:

सरल सिनात्रा एमवीसी

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


1

बड़ी परियोजनाओं के लिए सिनात्रा पर मॉड्यूलरिटी की कुंजी अंतर्निहित उपकरणों का उपयोग करना सीख रही है।

SitePoint में एक बहुत अच्छा ट्यूटोरियल है जहाँ से आप मॉड्यूलर सिनात्रा ऐप और हेल्पर्स देख सकते हैं। हालाँकि आपको एक महत्वपूर्ण विवरण पर विशेष ध्यान देना चाहिए। आप कई सिनात्रा ऐप रखते हैं और उन्हें रैकअप के साथ माउंट करते हैं। एक बार जब आप जानते हैं कि मूल ऐप कैसे लिखना है, तो उस ट्यूटोरियल की config.ru फ़ाइल को देखें और देखें कि वे स्वतंत्र सिनात्रा ऐप को कैसे माउंट करते हैं।

एक बार जब आप रैक के साथ सिनात्रा चलाना सीखते हैं तो मॉड्यूलरिटी रणनीतियों की एक पूरी दुनिया खुल जाएगी। यह स्पष्ट रूप से कुछ वास्तव में उपयोगी प्रयास करने के लिए आमंत्रित करता है: अब आप प्रत्येक उप अनुप्रयोग के लिए अलग-अलग रत्न होने पर भरोसा कर सकते हैं , जो आपको अपने मॉड्यूल को आसानी से संस्करण करने में सक्षम कर सकते हैं।

अपने ऐप के लिए मणि-मॉड्यूल का उपयोग करने की शक्ति को कम मत समझो। आप अच्छी तरह से सीमांकित वातावरण में प्रयोगात्मक परिवर्तनों का आसानी से परीक्षण कर सकते हैं और उन्हें आसानी से तैनात कर सकते हैं। यदि कुछ गलत हो जाता है तो समान रूप से वापस लौटना आसान है।

आपके कोड को व्यवस्थित करने के लिए एक हजार तरीके हैं, इसलिए यह रेल के समान एक लेआउट प्राप्त करने की कोशिश में चोट नहीं पहुंचाएगा। हालाँकि अपनी स्वयं की संरचना को अनुकूलित करने के तरीके के बारे में कुछ बेहतरीन पोस्ट भी हैं । यह पोस्ट अधिकांश वेब डेवलपर्स की अन्य लगातार जरूरतों को कवर करती है।

यदि आपके पास समय है, तो मैं आपको रूबी के बारे में अधिक जानने के लिए प्रोत्साहित करता हूं, जो किसी भी रूबी आधारित वेब अनुप्रयोग के लिए सामान्य आधार है। आपके काम करने के तरीके में इसका कम प्रभाव हो सकता है, लेकिन हमेशा कुछ कार्य ऐसे होते हैं जो ज्यादातर लोग अपने ऐप पर करते हैं जो कि रैक मिडलवेयर के रूप में बेहतर होते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.