Ruby on Rails 5.2 - ActionDispatch::Routing::Mapper::Scoping

मॉड्यूल ActionDispatch :: रूटिंग :: मैपर :: स्कोपिंग




ruby

मॉड्यूल ActionDispatch :: रूटिंग :: मैपर :: स्कोपिंग

आप एक नाम स्थान के तहत नियंत्रकों के समूह को व्यवस्थित करना चाह सकते हैं। आमतौर पर, आप एक admin नामस्थान के अंतर्गत कई प्रशासनिक नियंत्रकों का समूह बना सकते हैं। आप app/controllers/admin निर्देशिका के तहत इन नियंत्रकों को रखेंगे, और आप उन्हें अपने राउटर में एक साथ समूहित कर सकते हैं:

namespace "admin" do
  resources :posts, :comments
end

इससे प्रत्येक पोस्ट और टिप्पणी नियंत्रक के लिए कई मार्ग बन जाएंगे। Admin::PostsController , रेल बनाएंगे:

GET       /admin/posts
GET       /admin/posts/new
POST      /admin/posts
GET       /admin/posts/1
GET       /admin/posts/1/edit
PATCH/PUT /admin/posts/1
DELETE    /admin/posts/1

यदि आप व्यवस्थापन ( Admin::PostsController / एडमिन के बिना) को रूट करना चाहते हैं तो Admin::PostsController , आप उपयोग कर सकते हैं

scope module: "admin" do
  resources :posts
end

या, किसी एक मामले के लिए

resources :posts, module: "admin"

यदि आप PostsController ( Admin:: मॉड्यूल उपसर्ग के बिना) को रूट / एडमिन / पोस्ट करना चाहते हैं, तो आप उपयोग कर सकते हैं

scope "/admin" do
  resources :posts
end

या, किसी एक मामले के लिए

resources :posts, path: "/admin/posts"

इनमें से प्रत्येक मामले में, नामांकित मार्ग वैसे ही बने रहते हैं जैसे कि आपने गुंजाइश का उपयोग नहीं किया। अंतिम स्थिति में, PostsController लिए निम्नलिखित पथ मानचित्र:

GET       /admin/posts
GET       /admin/posts/new
POST      /admin/posts
GET       /admin/posts/1
GET       /admin/posts/1/edit
PATCH/PUT /admin/posts/1
DELETE    /admin/posts/1

सार्वजनिक प्रवृत्ति के तरीके

बाधाओं (बाधाओं = {}) {|| ...} स्रोत दिखाएं
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1007
def constraints(constraints = {})
  scope(constraints: constraints) { yield }
end

पैरामीटर प्रतिबंध

आपको नियमों के एक सेट के आधार पर नेस्टेड मार्गों को बाधित करने की अनुमति देता है। उदाहरण के लिए, id पैरामीटर में डॉट वर्ण के लिए अनुमति देने के लिए मार्गों को बदलने के लिए:

constraints(id: /\d+\.\d+/) do
  resources :posts
end

अब /posts/1 जैसे रूट मान्य नहीं होंगे, बल्कि /posts/1.1 होंगे। id पैरामीटर को इस उदाहरण के लिए पारित बाधा से मेल खाना चाहिए।

आप अन्य मापदंडों को भी प्रतिबंधित करने के लिए इसका उपयोग कर सकते हैं:

resources :posts do
  constraints(post_id: /\d+\.\d+/) do
    resources :comments
  end
end

आईपी ​​पर आधारित प्रतिबंध

रूट्स को IP या IP पतों की एक निश्चित सीमा के लिए विवश किया जा सकता है:

constraints(ip: /192\.168\.\d+\.\d+/) do
  resources :posts
end

192.168 से कनेक्ट होने वाला कोई भी उपयोगकर्ता। * रेंज इस संसाधन को देख सकेगा, जहां इस सीमा के बाहर कनेक्ट करने वाले किसी भी उपयोगकर्ता को बताया जाएगा कि ऐसा कोई मार्ग नहीं है।

गतिशील अनुरोध मिलान

विशिष्ट मानदंडों के आधार पर मार्गों के अनुरोधों को बाधित किया जा सकता है:

constraints(-> (req) { req.env["HTTP_USER_AGENT"] =~ /iPhone/ }) do
  resources :iphones
end

यदि आप मार्गों के लिए बहुत जटिल हैं, तो आप इस तर्क को एक कक्षा में स्थानांतरित करने में सक्षम हैं। इस वर्ग के पास एक matches? होना चाहिए matches? इस पर परिभाषित विधि, जो या तो true हो जाती true यदि उपयोगकर्ता को उस मार्ग तक पहुंच दी जानी चाहिए, या यदि उपयोगकर्ता को नहीं करना चाहिए तो false

class Iphone
  def self.matches?(request)
    request.env["HTTP_USER_AGENT"] =~ /iPhone/
  end
end

इस कोड के लिए एक अपेक्षित जगह lib/constraints

इस वर्ग को इस प्रकार प्रयोग किया जाता है:

constraints(Iphone) do
  resources :iphones
end
नियंत्रक (नियंत्रक) {|| ...} स्रोत दिखाएं
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 892
def controller(controller)
  @scope = @scope.new(controller: controller)
  yield
ensure
  @scope = @scope.parent
end

एक विशिष्ट नियंत्रक के लिए मार्ग मार्ग

controller "food" do
  match "bacon", action: :bacon, via: :get
end
चूक (चूक = {}) {|| ...} स्रोत दिखाएं
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1016
def defaults(defaults = {})
  @scope = @scope.new(defaults: merge_defaults_scope(@scope[:defaults], defaults))
  yield
ensure
  @scope = @scope.parent
end

आपको किसी रूट के लिए डिफ़ॉल्ट पैरामीटर सेट करने की अनुमति देता है, जैसे कि:

defaults id: 'home' do
  match 'scoped_pages/(:id)', to: 'pages#show'
end

इसका उपयोग करते हुए, यहाँ :id पैरामीटर 'होम' के लिए डिफॉल्ट होगा।

नाम स्थान (पथ, विकल्प = {}) {|| ...} स्रोत दिखाएं
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 937
def namespace(path, options = {})
  path = path.to_s

  defaults = {
    module:         path,
    as:             options.fetch(:as, path),
    shallow_path:   options.fetch(:path, path),
    shallow_prefix: options.fetch(:as, path)
  }

  path_scope(options.delete(:path) { path }) do
    scope(defaults.merge!(options)) { yield }
  end
end

एक विशिष्ट नाम स्थान के लिए स्कोप मार्ग। उदाहरण के लिए:

namespace :admin do
  resources :posts
end

यह निम्नलिखित मार्ग उत्पन्न करता है:

    admin_posts GET       /admin/posts(.:format)          admin/posts#index
    admin_posts POST      /admin/posts(.:format)          admin/posts#create
 new_admin_post GET       /admin/posts/new(.:format)      admin/posts#new
edit_admin_post GET       /admin/posts/:id/edit(.:format) admin/posts#edit
     admin_post GET       /admin/posts/:id(.:format)      admin/posts#show
     admin_post PATCH/PUT /admin/posts/:id(.:format)      admin/posts#update
     admin_post DELETE    /admin/posts/:id(.:format)      admin/posts#destroy

विकल्प

:path :as में :module :shallow_path और :shallow_prefix विकल्प सभी नामस्थान के नाम के लिए डिफ़ॉल्ट हैं।

विकल्पों के लिए, Base#match देखें। के लिए :shallow_path विकल्प, Resources#resources देखें।

# accessible through /sekret/posts rather than /admin/posts
namespace :admin, path: "sekret" do
  resources :posts
end

# maps to <tt>Sekret::PostsController</tt> rather than <tt>Admin::PostsController</tt>
namespace :admin, module: "sekret" do
  resources :posts
end

# generates +sekret_posts_path+ rather than +admin_posts_path+
namespace :admin, as: "sekret" do
  resources :posts
end
गुंजाइश (* args) {|| ...} स्रोत दिखाएं
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 833
def scope(*args)
  options = args.extract_options!.dup
  scope = {}

  options[:path] = args.flatten.join("/") if args.any?
  options[:constraints] ||= {}

  unless nested_scope?
    options[:shallow_path] ||= options[:path] if options.key?(:path)
    options[:shallow_prefix] ||= options[:as] if options.key?(:as)
  end

  if options[:constraints].is_a?(Hash)
    defaults = options[:constraints].select do |k, v|
      URL_OPTIONS.include?(k) && (v.is_a?(String) || v.is_a?(Integer))
    end

    options[:defaults] = defaults.merge(options[:defaults] || {})
  else
    block, options[:constraints] = options[:constraints], {}
  end

  if options.key?(:only) || options.key?(:except)
    scope[:action_options] = { only: options.delete(:only),
                               except: options.delete(:except) }
  end

  if options.key? :anchor
    raise ArgumentError, "anchor is ignored unless passed to `match`"
  end

  @scope.options.each do |option|
    if option == :blocks
      value = block
    elsif option == :options
      value = options
    else
      value = options.delete(option) { POISON }
    end

    unless POISON == value
      scope[option] = send("merge_#{option}_scope", @scope[option], value)
    end
  end

  @scope = @scope.new scope
  yield
  self
ensure
  @scope = @scope.parent
end

दिए गए डिफ़ॉल्ट विकल्पों में मार्गों का एक सेट स्कोप करें।

उदाहरण के रूप में निम्नलिखित मार्ग की परिभाषा लें:

scope path: ":account_id", as: "account" do
  resources :projects
end

यह मददगार बनाता है जैसे कि account_projects_path , जैसे resources करता है। यहाँ अंतर यह है कि उत्पन्न होने वाले मार्ग / / account_id / परियोजनाओं के बजाय / खातों /: account_id / परियोजनाओं की तरह हैं।

विकल्प

Base#match और Resources#resources समान विकल्प लेता है।

# route /posts (without the prefix /admin) to <tt>Admin::PostsController</tt>
scope module: "admin" do
  resources :posts
end

# prefix the posts resource's requests with '/admin'
scope path: "/admin" do
  resources :posts
end

# prefix the routing helper name: +sekret_posts_path+ instead of +posts_path+
scope as: "sekret" do
  resources :posts
end