Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

AngularJS और रेल के साथ शुरुआत करना 4

AngularJS के साथ शुरुआत करना कठिन नहीं है। दस्तावेज़ीकरण वहाँ से कुछ बेहतरीन है और इसके ट्यूटोरियल काफी सरल हैं।

लेकिन जब आप तकनीकों का संयोजन शुरू करते हैं तो चीजें मुश्किल हो जाती हैं।

यदि आप सीधे जावास्क्रिप्ट के बजाय कॉफीस्क्रिप्ट का उपयोग कर रहे हैं, तो आप जानते हैं कि प्रीप्रोसेसिंग चिंताओं को ध्यान में रखना है - साथ ही स्पष्ट वाक्यविन्यास अंतर भी। ये अपने आप में मामूली मुद्दे हैं, लेकिन क्या होगा यदि आप रूबी ऑन रेल्स, जैस्मीन और कर्मा को मिक्स में फेंक दें? यह आश्चर्यजनक रूप से पेचीदा हो जाता है।

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

यह ट्यूटोरियल मानता है कि आप रेल के साथ सहज हैं, लेकिन जरूरी नहीं कि एंगुलरजेएस।

बेस रेल ऐप बनाना

चूंकि इसमें बहुत सारी तकनीकी परतें शामिल हैं, इसलिए मैं एक साधारण एप्लिकेशन बनाने जा रहा हूं जो मुश्किल से कुछ भी करता है। हम रेस्तरां के लिए सीआरयूडी कार्यक्षमता स्थापित करेंगे - वास्तव में, केवल सीआर भाग। -यूडी को पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है।;-)

हम एप्लिकेशन को रेस्टोरेंटर . कहेंगे ।

मैं यहां पोस्टग्रेएसक्यूएल और आरएसपीईसी का उपयोग कर रहा हूं, लेकिन डीबीएमएस और सर्वर-साइड टेस्टिंग फ्रेमवर्क महत्वपूर्ण नहीं हैं। आप जो चाहें उपयोग कर सकते हैं।

आरंभिक सेटअप

पहले प्रोजेक्ट बनाएं:

$ rails new restauranteur --database=postgresql --skip-test-unit

यदि आप पाउ का उपयोग कर रहे हैं, तो अपने प्रोजेक्ट को पॉव में जोड़ें:

$ ln -s /Users/jasonswett/projects/restauranteur ~/.pow/restauranteur

PostgreSQL डेटाबेस उपयोगकर्ता बनाएँ:

$ createuser -P -s -e restauranteur

अपने Gemfile में RSpec जोड़ें:

# Gemfile
gem "rspec-rails", "~> 2.14.0"

आरएसपीईसी स्थापित करें:

$ bundle install
$ rails g rspec:install

डेटाबेस बनाएं:

$ rake db:create

रेस्तरां मॉडल बनाना

अब जब हमने अपना प्रोजेक्ट और डेटाबेस बना लिया है, तो चलिए अपना पहला संसाधन बनाते हैं। रेस्तरां संसाधन में केवल एक विशेषता होगी:नाम , जो एक स्ट्रिंग है।

$ rails generate scaffold restaurant name:string

अब, इसके बारे में ओसीडी होने के लिए, हम सुनिश्चित करेंगे कि रेस्तरां के नाम अद्वितीय हों।

# db/migrate/[timestamp]_create_restaurants.rb

class CreateRestaurants < ActiveRecord::Migration
  def change
    create_table :restaurants do |t|
      t.string :name

      t.timestamps
    end

    # Add the following line
    add_index :restaurants, :name, unique: true
  end
end

माइग्रेशन चलाएँ:

$ rake db:migrate

यह सत्यापित करने के लिए कि हम अमान्य रेस्तरां नहीं बना सकते, कुछ विशिष्टताएँ जोड़ते हैं। ध्यान दें कि अद्वितीय विफलता कच्ची त्रुटि देती है।

require 'spec_helper'

describe Restaurant do
  before do
    @restaurant = Restaurant.new(name: "Momofuku")
  end

  subject { @restaurant }

  it { should respond_to(:name) }
  it { should be_valid }

  describe "when name is not present" do
    before { @restaurant.name = " " }
    it { should_not be_valid }
  end

  describe "when name is already taken" do
    before do
      restaurant_with_same_name = @restaurant.dup
      restaurant_with_same_name.name = @restaurant.name.upcase
      restaurant_with_same_name.save
    end

    it { should_not be_valid }
  end
end

इन सत्यापनकर्ताओं को जोड़ने से विनिर्देश पास हो जाएंगे:

class Restaurant < ActiveRecord::Base 
  validates :name, presence: true, uniqueness: { case_sensitive: false }
end

अब हम आगे बढ़ने के लिए तैयार हैं।

AngularJS को मिश्रण में लाना

एक बार में आप पर सब कुछ डंप करने के बजाय, मैं पहले एंगुलरजेएस-रेल एप्लिकेशन का सबसे सरल "हैलो, वर्ल्ड" संस्करण प्रदर्शित करना चाहता हूं और फिर उस पर हमारे रेस्तरां सीआरयूडी कार्यक्षमता का निर्माण करना चाहता हूं।

कोई कारण नहीं है कि हमारा "हैलो, वर्ल्ड" पेज किसी विशेष रेल संसाधन से जुड़ा होना चाहिए या होना चाहिए। इस कारण से, हम एक StaticPagesController बनाएंगे हमारे AngularJS होम पेज की सेवा के लिए।

नियंत्रक बनाएं

$ rails generate controller static_pages index

अभी हमारा रूट रूट "वेलकम टू रेल्स" पेज है। आइए इसे index पर सेट करें हमारे नए StaticPagesController . की कार्रवाई :

# config/routes.rb

Restauranteur::Application.routes.draw do
  # Add the following line
  root 'static_pages#index'
end

कोणीय डाउनलोड करें

  1. अपने परीक्षणों को बाद में ठीक से काम करने के लिए, हमें angular-mocks.js नामक एक फ़ाइल की आवश्यकता होगी . मुझे नहीं लगता कि एंगुलर डॉक्स में कहीं भी इसका कोई उल्लेख है, लेकिन यह आवश्यक है।
  2. AngularJS ट्यूटोरियल में, डॉक्स नवीनतम ब्लीडिंग-एज संस्करण को सूचीबद्ध करता है, लेकिन अगर मुझे सही से याद है, तो मुझेangular.js के बीच संगतता के साथ समस्या थी। और angular-mocks.js नवीनतम संस्करण के लिए। मुझे पता है कि संस्करण 1.1.5 एक साथ काम करते हैं, इसलिए भले ही यह नवीनतम स्थिर संस्करण नहीं है, यह वह संस्करण है जिसे मैं यहां सूचीबद्ध कर रहा हूं। निश्चित रूप से समय के साथ अनुकूलता की स्थिति में सुधार होगा।

डाउनलोड करें angular.js और angular-mocks.js code.angularjs.org से और फाइलों को app/assets/javascripts में ले जाएं ।

$ wget https://code.angularjs.org/1.1.5/angular.js \
https://code.angularjs.org/1.1.5/angular-mocks.js
$ mv angular* app/assets/javascripts

इसे एसेट पाइपलाइन में जोड़ें

अब हम अपने एप्लिकेशन को AngularJS फ़ाइल की आवश्यकता के बारे में बताना चाहते हैं, और हम यह सुनिश्चित करना चाहते हैं कि यह उस पर निर्भर अन्य फ़ाइलों से पहले लोड हो जाए। (हम इन निर्भरताओं को प्रबंधित करने के लिए RequJS जैसे कुछ का उपयोग कर सकते हैं, और शायद यही वह है जो मैं उत्पादन उत्पाद पर करूँगा, लेकिन इस ट्यूटोरियल के प्रयोजनों के लिए मैं जितना संभव हो सके प्रौद्योगिकी स्टैक को पतला रखना चाहता हूं।)

नोट: कोणीय और टर्बोलिंक एक दूसरे के साथ संघर्ष कर सकते हैं, इसलिए हम उन्हें यहां अक्षम कर देते हैं

// app/assets/javascripts/application.js

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs

// Add the following two lines
//= require angular
//= require main

//= require_tree .

लेआउट सेट करें

हम एनजी-ऐप और एनजी-व्यू जोड़ेंगे, जो संकेत देते हैं कि हमारे पेज में एक एंगुलर ऐप है। यह भी ध्यान दें कि Turbolinks के उल्लेख हटा दिए गए हैं।

  <%= yield %>

एक कोणीय नियंत्रक बनाना

पहले हमारे नियंत्रकों के लिए एक निर्देशिका बनाते हैं। आप इसे जो चाहें नाम दे सकते हैं।

$ mkdir -p app/assets/javascripts/angular/controllers

अब कंट्रोलर फाइल को ही बनाते हैं। मैं इस कंट्रोलर को "होम कंट्रोलर" कह रहा हूं और एंगुलर में कन्वेंशन आपके कंट्रोलर फाइलनाम को Ctrl के साथ जोड़ना है। . इस प्रकार हमारा फ़ाइल नाम होगाapp/assets/javascripts/angular/controllers/HomeCtrl.js.coffee :

# app/assets/javascripts/angular/controllers/HomeCtrl.js.coffee

@restauranteur.controller 'HomeCtrl', ['$scope', ($scope) ->
  # Notice how this controller body is empty
]

एक कोणीय मार्ग जोड़ें

अब हम अपना HomeCtrl . बनाने के लिए एक रूटिंग निर्देश जोड़ेंगे हमारा "डिफ़ॉल्ट पृष्ठ" बनें। यहां मैं अपनी रूटिंग को app/assets/javascripts/main.js.coffee में परिभाषित कर रहा हूं , लेकिन फिर से मुझे नहीं लगता कि फ़ाइल नाम मायने रखता है।

# app/assets/javascripts/main.js.coffee

# This line is related to our Angular app, not to our
# HomeCtrl specifically. This is basically how we tell
# Angular about the existence of our application.
@restauranteur = angular.module('restauranteur', [])

# This routing directive tells Angular about the default
# route for our application. The term "otherwise" here
# might seem somewhat awkward, but it will make more
# sense as we add more routes to our application.
@restauranteur.config(['$routeProvider', ($routeProvider) ->
  $routeProvider.
    otherwise({
      templateUrl: '../templates/home.html',
      controller: 'HomeCtrl'
    }) 
])

एक कोणीय टेम्प्लेट जोड़ें

हम अपने एंगुलर टेम्प्लेट को रखने के लिए एक जगह भी चाहते हैं। मैंने अपना public/templates में डालने का निर्णय लिया . दोबारा, आप उन्हें जहां चाहें वहां रख सकते हैं।

mkdir public/templates

अगर हम एक फ़ाइल बनाते हैं public/templates/home.html कुछ मनमानी सामग्री के साथ, हमें इसे ब्राउज़र में देखने में सक्षम होना चाहिए।


This is the home page.

अब, यदि आप https://restauranteur.dev/ . पर जाते हैं (या https://localhost:3000/ यदि आप पाउ का उपयोग नहीं कर रहे हैं) और आपको home.html . की सामग्री देखनी चाहिए ।

डेटा बाइंडिंग का एक उदाहरण

यह तरह का है दिलचस्प है, लेकिन शायद बहुत प्रभावशाली नहीं है। आइए वास्तव में तार के पार कुछ भेजें। अपनाapp/assets/angular/controllers/HomeCtrl.js.coffee संपादित करें इस तरह:

# app/assets/angular/controllers/HomeCtrl.js.coffee 

@restauranteur.controller 'HomeCtrl', ['$scope', ($scope) -> 
  $scope.foo = 'bar'
]

यह कहने के समान ही है @foo = "bar" एक रेल नियंत्रक में। हम प्लग कर सकते हैंfoo इस तरह से डबल-ब्रेस सिंटैक्स का उपयोग करके टेम्पलेट में:

Value of "foo": {{foo}}  

इस बार वास्तविक रूप से करना

हमने पहले ही एक सरल हैलो वर्ल्ड ऐप बना लिया है। एक पूर्ण विकसित सीआरयूडी एप्लिकेशन बनाना ज्यादा कठिन नहीं है।

डेटाबेस को सीड करें

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

# db/seeds.rb

Restaurant.create([
  { name: "The French Laundry" },
  { name: "Chez Panisse" },
  { name: "Bouchon" },
  { name: "Noma" },
  { name: "Taco Bell" },
])
rake db:seed

रेस्तरां अनुक्रमणिका पृष्ठ बनाना

सबसे पहले रेस्टोरेंट के लिए एक टेम्प्लेट फोल्डर बनाते हैं:

mkdir public/templates/restaurants

पहला टेम्प्लेट जो हम बनाएंगे वह इंडेक्स पेज है:

[index](/#)

  * {{ restaurant.name }}

मैं एक पल में समझाता हूँ कि इन बातों का क्या अर्थ है। सबसे पहले नियंत्रक बनाते हैं:

# app/assets/javascripts/angular/controllers/RestaurantIndexCtrl.js.coffee

@restauranteur.controller 'RestaurantIndexCtrl', ['$scope', '$location', '$http', ($scope, $location, $http) ->
  $scope.restaurants = []
  $http.get('./restaurants.json').success((data) ->
    $scope.restaurants = data
  )
]

अंत में, हम अपने रूटिंग कॉन्फ़िगरेशन को समायोजित करेंगे:

# app/assets/javascripts/main.js.coffee

@restauranteur = angular.module('restauranteur', [])

@restauranteur.config(['$routeProvider', ($routeProvider) ->
  $routeProvider.
    when('/restaurants', {
      templateUrl: '../templates/restaurants/index.html',
      controller: 'RestaurantIndexCtrl'
    }).
    otherwise({
      templateUrl: '../templates/home.html',
      controller: 'HomeCtrl'
    })
])

अब, अंत में, हम URI /#/restaurants में जा सकते हैं और हमें अपने रेस्तरां की सूची देखने में सक्षम होना चाहिए। इससे पहले कि हम आगे बढ़ें, आइए एक परीक्षण जोड़ें।

अपना पहला परीक्षण जोड़ना

JS परीक्षण फ़ोल्डर जोड़ें:

mkdir spec/javascripts

परीक्षण लिखें:

# spec/javascripts/controllers_spec.js.coffee

describe "Restauranteur controllers", ->
  beforeEach module("restauranteur")

  describe "RestaurantIndexCtrl", ->
    it "should set restaurants to an empty array", inject(($controller) ->
      scope = {}
      ctrl = $controller("RestaurantIndexCtrl",
        $scope: scope
      )
      expect(scope.restaurants.length).toBe 0
    )

कॉन्फिग जोड़ें:

// spec/javascripts/restauranteur.conf.js

module.exports = function(config) {
  config.set({
    basePath: '../..',

    frameworks: ['jasmine'],

    autoWatch: true,

    preprocessors: {
      '**/*.coffee': 'coffee'
    }, 

    files: [
      'app/assets/javascripts/angular.js',
      'app/assets/javascripts/angular-mocks.js',
      'app/assets/javascripts/main.js.coffee',
      'app/assets/javascripts/angular/controllers/RestaurantIndexCtrl.js.coffee',
      'app/assets/javascripts/angular/*',
      'spec/javascripts/*_spec.js.coffee'
    ]  
  });
};

कर्म स्थापित करें और सर्वर शुरू करें:

sudo npm install -g karma
sudo npm install -g karma-ng-scenario
karma start spec/javascripts/restauranteur.conf.js

अगर आप https://localhost:9876/ . पर जाते हैं , हमारा परीक्षण चलेगा और सफल होगा। यदि आप परीक्षण को विफल होते देखना चाहते हैं, तो expect(scope.restaurants.length).toBe 0 बदलें। toexpect(scope.restaurants.length).toBe 1 और फिर से परीक्षण चलाएँ।

इस परीक्षण की सार्थकता जो हमने अभी जोड़ी है, स्पष्ट रूप से संदिग्ध है, लेकिन मेरा इरादा यहां आपको यह पता लगाने के काम को बचाने के लिए है कि अपने एंगुलर कोड को टेस्ट हार्नेस में कैसे लाया जाए। कुछ चीजें हैं, जैसे कि CoffeeScript प्रीप्रोसेसर औरangular-mocks.js समावेशन जो पूरी तरह से स्पष्ट नहीं हैं और मुझे ठीक होने में कई घंटे लग गए।

रेस्तरां बनाना पृष्ठ

आइए अब अपने रेस्टोरेंट इंडेक्स टेम्प्लेट में एक अस्थायी समायोजन करें:

  * {{restaurant.name}} ({{restaurant.id}})

अगर आप अब /#/restaurants पर फिर से जाते हैं , आप देखेंगे कि किसी भी रेस्तरां के पास अपनी आईडी नहीं है। वे खाली क्यों हैं?

जब आप रेल 4 में मचान उत्पन्न करते हैं, तो यह आपको कुछ .jbuilder . देता है फ़ाइलें:

$ ls -1 app/views/restaurants/*.jbuilder
app/views/restaurants/index.json.jbuilder
app/views/restaurants/show.json.jbuilder

अगर आप app/views/restaurants/index.json.jbuilder खोलते हैं , आप इसे देखेंगे:

# app/views/restaurants/index.json.jbuilder

json.array!(@restaurants) do |restaurant|
  json.extract! restaurant, :name
  json.url restaurant_url(restaurant, format: :json)
end

जैसा कि आप देख सकते हैं, इसमें :name . शामिल है लेकिन नहीं :id . आइए इसे जोड़ें:

# app/views/restaurants/index.json.jbuilder

json.array!(@restaurants) do |restaurant|
  json.extract! restaurant, :id, :name
  json.url restaurant_url(restaurant, format: :json)
end

यदि आप फ़ाइल को सहेजते हैं और /#/restaurants को ताज़ा करते हैं , आपको आईडी दिखाई देनी चाहिए।

आइए अब टेम्प्लेट को वापस उसी तरह बदलते हैं जैसे वह मूल रूप से था:

[index](/#)

  * {{ restaurant.name }}

आपने कभी गौर किया होगा कि हम इन चीज़ों को viewRestaurant() नाम की किसी चीज़ की तरफ़ इशारा कर रहे हैं लेकिन हमने वास्तव में कभी भी viewRestaurant() . नामक कुछ भी परिभाषित नहीं किया है . चलिए अब करते हैं:

# app/assets/javascripts/angular/controllers/RestaurantIndexCtrl.js.coffee

@restauranteur.controller 'RestaurantIndexCtrl', ['$scope', '$location', '$http', ($scope, $location, $http) ->
  $scope.restaurants = []
  $http.get('./restaurants.json').success((data) ->
    $scope.restaurants = data
  )

  # Add the following lines
  $scope.viewRestaurant = (id) ->
    $location.url "/restaurants/#{id}"
]

रेल में सम्मेलन यह है कि resource_name/:id एक "शो" पृष्ठ पर मैप करता है, और यही हम यहां करेंगे। आइए एक शो टेम्प्लेट, रूट और कंट्रोलर बनाएं।

# {{restaurant.name}}
# app/assets/javascripts/main.js.coffee

@restauranteur = angular.module('restauranteur', [])

@restauranteur.config(['$routeProvider', ($routeProvider) ->
  $routeProvider.
    when('/restaurants', {
      templateUrl: '../templates/restaurants/index.html',
      controller: 'RestaurantIndexCtrl'
    }).
    when('/restaurants/:id', {
      templateUrl: '../templates/restaurants/show.html',
      controller: 'RestaurantShowCtrl'
    }).
    otherwise({
      templateUrl: '../templates/home.html',
      controller: 'HomeCtrl'
    })
])
# app/assets/javascripts/angular/controllers/RestaurantShowCtrl.js.coffee

@restauranteur.controller 'RestaurantShowCtrl', ['$scope', '$http', '$routeParams', ($scope, $http, $routeParams) ->
  $http.get("./restaurants/#{$routeParams.id}.json").success((data) ->
    $scope.restaurant = data
  )
]

अब अगर आप /#/restaurants को रिफ्रेश करते हैं और एक रेस्तरां पर क्लिक करें, आपको उस रेस्तरां के शो पेज पर खुद को ढूंढना चाहिए। जय!

अभी के लिए बस इतना ही

हमने विशेष रूप से प्रभावशाली परिणाम नहीं देखे होंगे, लेकिन मुझे आशा है कि मैंने आपको AngularJS को रेल 4 में प्लग करने में कुछ समय बचा लिया है। इसके बाद मैं inngResource देखने की सिफारिश कर सकता हूं, जो CRUD की कार्यक्षमता को और अधिक शुष्क बनाने में मदद कर सकता है।

अधिक सीखने में रुचि रखते हैं?

एडम एंडरसन की महान पोस्ट देखें, जिसकी रेल 4.0 श्रृंखला में एंगुलरजेएस ऐप को बूटस्ट्रैप करने से मुझे एंगुलरजेएस और रेल के साथ शुरुआत करने में मदद मिली। आप उनके ट्यूटोरियल को भी पढ़ना पसंद कर सकते हैं, लेकिन यह ट्यूटोरियल इस मायने में अलग है कि मैं आपको सभी विवरणों को _वास्तव में_चम्मच-फीड करने की कोशिश करता हूं, जिससे आपके मातम में फंसने की संभावना कम हो जाती है।


  1. GitHub Marketplace के साथ शुरुआत करना:अपने ऐप्स और टूल्स को कैसे सूचीबद्ध करें

    अपने गिटहब मार्केटप्लेस ऐप के साथ डेवलपर्स गिटहब वर्कफ़्लो में सुधार करना चाहते हैं? गिटहब मार्केटप्लेस एक ऐसी जगह है जहां डेवलपर्स फ्री और पेड टूल्स का इस्तेमाल कर सकते हैं। प्लेटफ़ॉर्म डेवलपर्स को विभिन्न प्रकार के टूल प्रदान करता है जैसे क्रियाएँ और ऐप्स, जहाँ प्रत्येक टूल को प्लेटफ़ॉर्म में जोड़

  1. वेब के लिए Android संदेशों के साथ आरंभ करना

    Google एक विशाल मंच है और इसमें कोई संदेह नहीं है! लेकिन सबसे अच्छे सर्च इंजनों में से एक होने के अलावा, यह हमें कई तरह की सेवाएं भी प्रदान करता है जो हमारे दैनिक जीवन को आसान बनाती हैं। Google ने हाल ही में Android संदेश ऐप के लिए एक अपडेट जारी किया है जो आपको किसी भी वेब ब्राउज़र से पाठ संदेश भेजन

  1. Xen वर्चुअलाइजेशन के साथ शुरुआत करना

    ज़ेन, Z के साथ वर्तनी, आठ घंटे तक पकड़े रहने के बाद बर्फ में पेशाब करते समय आपके सिर के मुकुट पर सर्वोत्कृष्ट अनुभूति होती है। Xen, X के साथ वर्तनी, एक ओपन-सोर्स वर्चुअलाइजेशन तकनीक है जिसे आप अपने सेटअप के लिए विचार कर सकते हैं, चाहे घर या व्यवसाय में, हालांकि, KVM की तरह, यह कॉर्पोरेट बाजार में अध