खोज…


परिचय

एमवीसी में एक्शन कंट्रोलर सी है। राउटर ने यह निर्धारित करने के बाद कि किस नियंत्रक को अनुरोध के लिए उपयोग करना है, नियंत्रक अनुरोध की समझ बनाने और आउटपुट का उत्पादन करने के लिए जिम्मेदार है।

नियंत्रक अनुरोध प्राप्त करेगा, एक मॉडल से डेटा प्राप्त करेगा या सहेजेगा और आउटपुट बनाने के लिए एक दृश्य का उपयोग करेगा। एक नियंत्रक को मॉडल और विचारों के बीच एक बिचौलिया के रूप में सोचा जा सकता है। यह मॉडल डेटा को दृश्य के लिए उपलब्ध कराता है ताकि यह उपयोगकर्ता को प्रदर्शित कर सके, और यह उपयोगकर्ता डेटा को मॉडल में सहेजता है या अपडेट करता है।

HTML के बजाय आउटपुट JSON

class UsersController < ApplicationController
  def index
    hashmap_or_array = [{ name: "foo", email: "[email protected]" }]

    respond_to do |format|
      format.html { render html: "Hello World" }
      format.json { render json: hashmap_or_array }
    end
  end
end

इसके अलावा आपको मार्ग की आवश्यकता होगी:

resources :users, only: [:index]

यह /users से अनुरोध करने के दो अलग-अलग तरीकों से प्रतिक्रिया देगा:

  • यदि आप /users या /users.html , तो यह सामग्री Hello World साथ एक html पृष्ठ दिखाएगा
  • यदि आप /users.json पर /users.json , तो यह JSON ऑब्जेक्ट प्रदर्शित करेगा:
[
  {
    "name": "foo",
    "email": "[email protected]"
  }
]

आप format.html { render inline: "Hello World" } को छोड़ सकते हैं format.html { render inline: "Hello World" } यदि आप यह सुनिश्चित करना चाहते हैं कि आपका मार्ग केवल JSON अनुरोधों का जवाब देगा।

नियंत्रकों (मूल)

class UsersController < ApplicationController
  def index
    respond_to do |format|
      format.html { render html: "Hello World" }
    end
  end
end

यह एक मूल नियंत्रक है, जिसमें निम्न मार्ग (मार्गों में शामिल हैं ।rb):

resources :users, only: [:index]

जब आप URL /users एक्सेस करते हैं तो एक वेबपेज में Hello World संदेश प्रदर्शित करेगा

पैरामीटर

नियंत्रकों की पहुंच HTTP मापदंडों तक होती है (आप उन्हें URL के रूप में जानते हैं ?name=foo URLs में, लेकिन रूबी ऑन रेल्स विभिन्न स्वरूपों को भी संभालते हैं!) और उनके आधार पर विभिन्न प्रतिक्रियाओं का उत्पादन करते हैं। GET और POST मापदंडों के बीच अंतर करने का कोई तरीका नहीं है, लेकिन आपको किसी भी मामले में ऐसा नहीं करना चाहिए।

class UsersController < ApplicationController
  def index
    respond_to do |format|
      format.html do
        if params[:name] == "john"
          render html: "Hello John"
        else
          render html: "Hello someone"
        end
      end
    end 
  end
end

हमेशा की तरह हमारा मार्ग:

resources :users, only: [:index]

URL /users?name=john तक पहुंचें /users?name=john और आउटपुट Hello John , एक्सेस /users?name=whatever और आउटपुट Hello someone

फ़िल्टरिंग पैरामीटर (मूल)

class UsersController < ApplicationController
  def index
    respond_to do |format|
      format.html do
        render html: "Hello #{ user_params[:name] } user_params[:sentence]"
      end
    end 
  end

  private

  def user_params
    if params[:name] == "john"
      params.permit(:name, :sentence)
    else
      params.permit(:name)
    end
  end
end

आप कुछ पैरामेट्स की अनुमति दे सकते हैं (या अस्वीकार कर सकते हैं), ताकि आप जो चाहते हैं, केवल वही पास हो और आपको खराब आश्चर्य न हो जैसे उपयोगकर्ता सेटिंग विकल्प को बदलना नहीं है।

विजिटिंग /users?name=john&sentence=developer Hello john developer /users?name=john&sentence=developer को प्रदर्शित करेगा, हालांकि विजिटिंग /users?name=smith&sentence=spy केवल Hello smith को प्रदर्शित करेगा, क्योंकि :sentence की अनुमति केवल तब होती है जब आप john रूप में एक्सेस करते हैं

पुन: निर्देशित

मार्ग मानकर:

resources :users, only: [:index]

आप किसी भिन्न URL का उपयोग करके पुनर्निर्देशित कर सकते हैं:

class UsersController
  def index
    redirect_to "http://stackoverflow.com/"
  end
end

आप उपयोग किए गए उपयोगकर्ता के पिछले पृष्ठ पर वापस जा सकते हैं:

redirect_to :back

ध्यान दें कि रेल 5 में पुनर्निर्देशन के लिए वाक्यविन्यास अलग है:

redirect_back fallback_location: "http://stackoverflow.com/"

जो पिछले पृष्ठ पर पुनर्निर्देशित करने की कोशिश करेगा और संभव नहीं होने पर (ब्राउज़र HTTP_REFERRER शीर्ष लेख को अवरुद्ध कर रहा है), यह पुनर्निर्देशित करेगा :fallback_location

दृश्यों का उपयोग करना

मार्ग मानकर:

resources :users, only: [:index]

और नियंत्रक:

class UsersController < ApplicationController
  def index
    respond_to do |format|
      format.html { render }
    end
  end
end

दृश्य app/users/index.html.erb प्रदान किया जाएगा। यदि दृश्य है:

Hello <strong>World</strong>

आउटपुट पाठ के साथ एक वेबपेज होगा: "हैलो वर्ल्ड "

यदि आप एक अलग दृश्य प्रस्तुत करना चाहते हैं, तो आप उपयोग कर सकते हैं:

render "pages/home"

और इसके बजाय फ़ाइल app/views/pages/home.html.erb का उपयोग किया जाएगा।

आप नियंत्रक उदाहरण चर का उपयोग करके विचारों को चर पास कर सकते हैं:

class UsersController < ApplicationController
  def index
    @name = "john"

    respond_to do |format|
      format.html { render }
    end
  end
end

और फ़ाइल app/views/users/index.html.erb आप @name उपयोग कर सकते हैं:

Hello <strong><%= @name %></strong>

और आउटपुट होगा: "हेलो जॉन "

रेंडर सिंटैक्स के चारों ओर एक महत्वपूर्ण नोट, आप render सिंटैक्स को पूरी तरह से छोड़ सकते हैं, रेल मानती है कि यदि आप इसे छोड़ देते हैं। इसलिए:

class UsersController < ApplicationController
  def index
    respond_to do |format|
      format.html { render }
    end
  end
end

इसके बजाय लिखा जा सकता है:

class UsersController < ApplicationController
  def index
    respond_to do |format|
      format.html
    end
  end
end

रेल काफी स्मार्ट है यह पता लगाने के लिए कि उसे फ़ाइल app/views/users/index.html.erb को प्रस्तुत करना होगा।

404 जब रिकॉर्ड नहीं मिला

अपवाद या श्वेत पृष्ठ दिखाने के बजाय रिकॉर्ड से बचाव में त्रुटि नहीं मिली:

class ApplicationController < ActionController::Base
  
  # ... your other stuff here 

  rescue_from ActiveRecord::RecordNotFound do |exception|
    redirect_to root_path, 404, alert: 'Record not found'
  end
end

बेसिक रेस्ट कंट्रोलर

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  def index
    @posts = Post.all
  end

  def show
    
  end

  def new
    @post = Post.new
  end

  def edit

  end

  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post.company, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    def set_post
      @post = Post.find(params[:id])
    end

    def post_params
      params.require(:post).permit(:title, :body, :author)
    end
end

अपवादों के लिए त्रुटि पृष्ठ प्रदर्शित करें

यदि आप सरल "सॉरी, कुछ गलत हो गया" के बजाय अपने उपयोगकर्ताओं को सार्थक त्रुटियों को प्रदर्शित करना चाहते हैं, तो रेल का उद्देश्य के लिए एक अच्छी उपयोगिता है।

फ़ाइल app/controllers/application_controller.rb खोलें app/controllers/application_controller.rb और आपको इस तरह से कुछ ढूंढना चाहिए:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
end

विशिष्ट त्रुटियों से उबरने के लिए हम अब एक rescue_from जोड़ सकते हैं:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  rescue_from ActiveRecord::RecordNotFound, with: :record_not_found

  private

  def record_not_found
    render html: "Record <strong>not found</strong>", status: 404
  end
end

यह सलाह दी जाती है कि Exception या StandardError से बचाव न करें अन्यथा रेल त्रुटियों के मामले में सहायक पृष्ठ प्रदर्शित नहीं कर पाएंगे।

फिल्टर

फिल्टर एक विधि कार्रवाई के "पहले", "बाद" या "आसपास" चलाए जाने वाले तरीके हैं। वे विरासत में मिले हैं, इसलिए यदि आप अपने ApplicationController में कोई भी सेट करते हैं तो वे आपके अनुरोध को प्राप्त करने वाले हर अनुरोध के लिए चलाए जाएंगे।

फ़िल्टर करने से पहले

नियंत्रक कार्रवाई से पहले फ़िल्टर निष्पादित किए जाते हैं और अनुरोध (और / या पुनर्निर्देशित) को रोक सकते हैं। यदि उपयोगकर्ता लॉग इन है तो एक सामान्य उपयोग यह सत्यापित करना है:

class ApplicationController < ActionController::Base
  before_action :authenticate_user!

  def authenticate_user!
    redirect_to some_path unless user_signed_in?
  end
end

नियंत्रक की कार्रवाई के लिए अनुरोध मिलने से पहले फ़िल्टर अनुरोधों पर चलाए जाते हैं। यह स्वयं एक प्रतिक्रिया लौटा सकता है और कार्रवाई को पूरी तरह से बायपास कर सकता है।

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

फ़िल्टर के बाद

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

आमतौर पर, मैंने लॉगिंग के लिए उपयोग किए जाने वाले फ़िल्टर के बाद और उसके आसपास देखा है।

फ़िल्टर के आसपास

कार्रवाई चलाने से पहले और बाद में फ़िल्टर के पास तर्क हो सकते हैं। यह केवल उस जगह तक कार्रवाई करता है जो आवश्यक हो। ध्यान दें कि उसे कार्रवाई करने के लिए उपज की आवश्यकता नहीं है और एक पहले के फिल्टर की तरह ऐसा किए बिना चल सकता है।

रैक के बिचौलिये कैसे काम करते हैं, इसके हिसाब से फ़िल्टरिंग से संबंधित क्रियाओं को चलाने के लिए जिम्मेदार होते हैं।

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

यहाँ फ़िल्टर के आसपास का एक उदाहरण दिया गया है:

around_filter :catch_exceptions
 
private
  def catch_exceptions
    begin
      yield
    rescue Exception => e 
      logger.debug "Caught exception! #{e.message}"
    end
  end

यह किसी भी कार्रवाई के अपवाद को पकड़ लेगा और आपके लॉग में संदेश डाल देगा। आप अपवाद हैंडलिंग, सेटअप और फाड़ के लिए फ़िल्टर और अन्य मामलों के असंख्य उपयोग कर सकते हैं।

केवल और सिवाय

सभी फ़िल्टर विशिष्ट कार्यों पर लागू किए जा सकते हैं, :only :except और :except

class ProductsController < ApplicationController
  before_action :set_product, only: [:show, :edit, :update]

  # ... controller actions

  # Define your filters as controller private methods
  private

  def set_product
    @product = Product.find(params[:id])
  end
end

स्किपिंग फ़िल्टर

सभी फ़िल्टर (कुछ भी विरासत में मिले) को कुछ विशिष्ट कार्यों के लिए छोड़ दिया जा सकता है:

class ApplicationController < ActionController::Base
  before_action :authenticate_user!

  def authenticate_user!
    redirect_to some_path unless user_signed_in?
  end
end

class HomeController < ApplicationController
  skip_before_action :authenticate_user!, only: [:index]

  def index
  end
end

जैसा कि उन्हें विरासत में मिला है, फ़िल्टर को एक namespace "मूल" नियंत्रक में भी परिभाषित किया जा सकता है। उदाहरण के लिए कहें कि आपके पास एक admin नाम स्थान है, और आप निश्चित रूप से केवल उपयोगकर्ताओं को ही इसे एक्सेस करने में सक्षम होना चाहते हैं। आप ऐसा कुछ कर सकते हैं:

# config/routes.rb
namespace :admin do
  resources :products
end

# app/controllers/admin_controller.rb
class AdminController < ApplicationController
  before_action :authenticate_admin_user!

  private

  def authenticate_admin_user!
    redirect_to root_path unless current_user.admin?
  end
end

# app/controllers/admin/products_controller.rb
class Admin::ProductsController < AdminController
  # This controller will inherit :authenticate_admin_user! filter
end

खबरदार रेल में 4.x कि आप इस्तेमाल कर सकते हैं before_filter के साथ before_action , लेकिन before_filter वर्तमान में रेल 5.0.0 में हटा दिया गया है और 5.1 में निकाल दिया जाएगा।

एक नियंत्रक उत्पन्न करना

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

आप अपने ऐप फ़ोल्डर में इस कमांड को चलाकर एक नया कंट्रोलर उत्पन्न कर सकते हैं

rails generate controller NAME [action action] [options]

नोट: आप rails generate करने के लिए rails generate rails g अलियास का भी उपयोग कर सकते हैं

उदाहरण के लिए, #index और #show क्रियाओं के साथ एक Product मॉडल के लिए एक नियंत्रक उत्पन्न करने के लिए, जो आप चलाएंगे

rails generate controller products index show

यह आपके द्वारा निर्दिष्ट दोनों क्रियाओं के साथ app/controllers/products_controller.rb में कंट्रोलर बनाएगा

class ProductsController < ApplicationController
  def index
  end

  def show
  end
end

यह app/views/ अंदर एक products फ़ोल्डर भी बनाएगा, जिसमें आपके नियंत्रक के कार्यों के लिए दो टेम्पलेट होंगे (जैसे index.html.erb और show.html.erb , ध्यान दें कि एक्सटेंशन आपके टेम्पलेट इंजन के अनुसार भिन्न हो सकता है, इसलिए यदि आप slim का उपयोग कर रहे हैं, उदाहरण के लिए, जनरेटर index.html.slim और show.html.slim बनाएगा )

इसके अलावा, यदि आपने कोई कार्य निर्दिष्ट किया है तो वे आपके routes फ़ाइल में भी जोड़े जाएंगे

# config/routes.rb
get 'products/show'
get 'products/index'

रेल आपके लिए app/helpers/products_helper.rb , और साथ ही app/assets/javascripts/products.js और app/assets/stylesheets/products.css में एसेट फाइल बनाती है। दृश्यों के लिए, जनरेटर आपके Gemfile में निर्दिष्ट किए गए अनुसार इस व्यवहार को Gemfile : यानी, यदि आप अपने आवेदन में Coffeescript और Sass का उपयोग कर रहे हैं, तो कंट्रोलर जनरेटर जनरेटर products.coffee और products.sass Coffeescript

अंत में, लेकिन कम से कम, रेल आपके नियंत्रक, आपके सहायक और आपके विचारों के लिए परीक्षण फ़ाइलें भी नहीं बनाता है।

यदि आप नहीं चाहते हैं कि इनमें से कोई भी आपके लिए बनाया जाए, तो आप रेल को उन्हें छोड़ने के लिए कह सकते हैं, बस किसी भी विकल्प के साथ प्रस्तुत करें

--no- या --skip , इस तरह:

rails generate controller products index show --no-assets --no-helper

और जनरेटर assets और helper दोनों को छोड़ देगा

यदि आपको किसी विशिष्ट namespace लिए एक नियंत्रक बनाने की आवश्यकता है, तो उसे NAME सामने जोड़ें:

rails generate controller admin/products

इससे app/controllers/admin/products_controller.rb अंदर आपका कंट्रोलर बन जाएगा

रेल भी आपके लिए एक पूर्ण RESTful नियंत्रक उत्पन्न कर सकती है:

rails generate scaffold_controller MODEL_NAME # available from Rails 4
rails generate scaffold_controller Product

ActiveRecord को बचाया :: RecordNotFound को redirect_to के साथ

आप एक त्रुटि पृष्ठ दिखाने के बजाय एक रीडायरेक्ट के साथ RecordNotFound अपवाद को छुड़ा सकते हैं:

class ApplicationController < ActionController::Base

  # your other stuff

  rescue_from ActiveRecord::RecordNotFound do |exception|
    redirect_to root_path, 404, alert: I18n.t("errors.record_not_found")
  end
end


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow