Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Tích Hợp Angular Với Rails 5: Cách Tiếp Cận Full-Stack Liền Mạch

Bạn đã nghe câu chuyện này trước đây. Bạn đã có một ứng dụng chạy trên back-end API phi tập trung và hoạt động đầy đủ, và front-end làm bằng bất kỳ toolset thông thường nào.

Bây giờ, bạn muốn chuyển sang Angular. Hoặc, có lẽ bạn chỉ đang tìm cách tích hợp Angular với dự án Rails của bạn vì bạn thích cách này. Chúng ta không trách bạn.

Với cách tiếp cận này, bạn có thể tận dụng cả hai thế giới và quyết định xem bạn có muốn dùng tính năng từ Rails hay Angular để format thứ gì đó, ví dụ.

Chúng Ta Sẽ Xây Dựng Gì

Không cần lo lắng. Hướng dẫn này được viết cho mục đích này. Chúng ta sẽ đi sâu vào việc tạo một ứng dụng CRUD hoàn toàn hoạt động trên domain người dùng (users).

Cuối bài viết, bạn sẽ đã học một số khái niệm cơ bản quanh Angular và cách thiết lập dự án Rails back-end tích hợp trực tiếp với Angular cho front-end, như hiển thị dưới:

Tích Hợp Angular Với Rails 5: Cách Tiếp Cận Full-Stack Liền Mạch CRUD người dùng làm bằng Rails và Angular

Ứng dụng sẽ xử lý cả bốn operation CRUD trên domain người dùng được lấy từ dịch vụ web giả lập bên ngoài (fake-testing web service). App sẽ được xây dựng trên kiến trúc MVC, với mỗi lớp Angular được giải thích chi tiết để giúp bạn hiểu tốt hơn cách mọi thứ gắn kết. Style sẽ dùng Bootstrap.

Thiết Lập (Setup)

Như bạn có thể đoán, chúng ta sẽ cần phần mềm sau:

  • Ruby (Tôi chọn phiên bản 2.7.0preview1),
  • Ruby và Rails (Tôi dùng phiên bản 5.0.7.2),
  • Node.js (Tôi dùng v13.7.0),
  • Yarn (Ít nhất phiên bản 1.22.4)

Hãy chắc chắn cài đặt mọi thứ đúng cách. Sau đó, chúng ta có thể chuyển sang dự án. Chọn thư mục bạn thích và chạy lệnh sau:

rails new crud-rails-angular

Đợi thiết lập hoàn tất và mở dự án trong IDE yêu thích. Chúng ta sẽ làm việc với VS Code cho bài này vì nó đơn giản, mạnh mẽ, và ôm lấy cả cú pháp Rails và Angular một cách mượt mà.

Nếu bạn đã dùng Rails 5 một thời gian, bạn có thể nhận thấy lệnh new của nó sinh ra bug trong Gemfile cho config SQLite. Nó đến không có phiên bản tối thiểu, và điều đó sẽ làm nó chạy với lỗi. Hãy sửa vấn đề này bằng cách cập nhật nó thành:

gem 'sqlite3', '~> 1.3.10'

Hoàn hảo!

Thiết Lập Webpacker

Cách tốt nhất để quản lý ứng dụng giống JavaScript trong Rails là thông qua Webpacker. Nó sử dụng Webpack phía sau để cung cấp tính năng, như pre-processing và bundling ứng dụng JavaScript, như Angular, vào ứng dụng Rails hiện có.

Để cài đặt nó, chỉ cần thêm dòng mới vào Gemfile của bạn:

gem 'webpacker', '~> 4.3.x'

Điều này sẽ đảm bảo bạn cài đặt phiên bản rất gần đây. Tiếp theo, chạy các lệnh sau:

bundle install
bundle exec rake webpacker:install
bundle exec rake webpacker:install:angular

Lệnh đầu tiên sẽ tải xuống và cập nhật các phụ thuộc Rails đã thêm.

Lệnh thứ hai tương đương với npm install vì nó tạo thư mục node_modules và cài đặt một đống phụ thuộc Angular bắt buộc, như Babel, Sass, Browserlist, và Webpack. Bây giờ, chúng ta có cả ứng dụng Node và Rails trong cùng dự án.

Trong lệnh cuối cùng, chúng ta có tương đương npm install angular, sẽ tải xuống tất cả phụ thuộc Angular bắt buộc và làm nó hoạt động cùng dự án Rails.

Cuối các lệnh này, bạn cũng có thể thấy tệp package.json được tạo. Tất cả phụ thuộc bắt buộc của chúng ta được đặt đó, và bạn có thể thêm bất cứ cái nào bạn cần trong tương lai.

Cũng, một vài thư mục và tệp được tạo dưới thư mục /app, như /javascript mới. Trong thư mục này, bạn đã có thư mục /hello_angular được tạo để hỗ trợ khởi đầu phát triển của bạn.

Để tiết kiệm thời gian, tôi sẽ nhờ bạn mirror cấu trúc thư mục và tệp với cái sau:

Tích Hợp Angular Với Rails 5: Cách Tiếp Cận Full-Stack Liền Mạch

Một Vài Điều Chỉnh Angular

Webpacker khuyến nghị một series điều chỉnh trong dự án Rails đã tạo. Vì vậy, hãy dành thời gian để tổ chức nhà cửa.

Trước tiên, mở tệp application.js đặt dưới thư mục /packs (hiển thị trong hình trên) và thêm code sau:

import "core-js/stable";
import "regenerator-runtime/runtime";

Các import này hoạt động như lực lượng phụ trợ để ổn định môi trường JavaScript trong dự án Rails.

Bây giờ, chúng ta cần thông báo cho Rails nơi nó phải lấy output cho các trang. Một khi Webpacker đóng gói xong, nó sẽ sinh ra một đống tệp tĩnh phân phối được mà Rails phải biết.

Đi đến tệp application.html.erb dưới thư mục app/views/layout và thay đổi nội dung thẻ <head> thành:


  CrudRailsAngular
   
  <%= csrf_meta_tags %>
  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
   
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  <%= javascript_pack_tag 'application' %> 

Hãy phân tích một chút:

  1. Ở đây, chúng ta thêm thẻ base, nói cho Rails biết nơi nhìn khi ứng dụng khởi động.
  2. Chúng ta sẽ dùng Bootstrap để suy diễn style cho trang, để chúng ta có thể tập trung vào implementation.
  3. Đây là nơi bạn phải đặt thẻ Webpacker map đến nội dung thư mục /packs (cùng cái sẽ được tự động tạo bởi Webpacker sau mỗi biên dịch).

Model Và Database

Tiến sang thiết lập database. Để làm nhanh hơn, chúng ta sẽ scaffold model mới tên User. Đây là lệnh bạn phải chạy để đạt được nó:

rails g scaffold User name:string age:integer address:text && rake db:migrate

Nó sẽ tạo tất cả thư mục và tệp model, mà chúng ta sẽ cần để Rails thao tác thông tin database (từ SQLite) và lưu trữ nó cho operation CRUD của chúng ta.

Sau đó, bạn sẽ thấy tệp mới XXX1_create_users.rb được tạo dưới thư mục db/migrate/. Mở nó, và bạn sẽ thấy bản ghi CreateUsers mới tạo.

Trong thư mục app/models/, bạn sẽ thấy model User được tạo tại tệp user.rb.

Bây giờ, mở tệp db/seeds.rb và thêm code sau:

User.create(name: 'Luke Wan', age: 23, address: '123 Test St.')
User.create(name: 'Mary Poppins', age: 41, address: '123 ABC St.')
User.create(name: 'John Neilman', age: 76, address: '000 Test St.')

Code này sẽ khởi tạo bảng Users với một vài dữ liệu khi khởi động. Lưu nó, và chạy lệnh:

rake db:seed

Điều này sẽ seed bảng qua các lệnh liệt kê trên. Tiếp theo, bạn có thể vào database SQLite và kiểm tra xem nó có hoạt động không bằng cách chạy lệnh:

sqlite3 db/development.sqlite3

Sau đó, chọn dữ liệu bảng:

select * from users;

và bạn có thể thấy kết quả.

Component User

Bạn sẽ cần cài đặt thêm một vài phụ thuộc để giúp chuyển đổi HTML và CSS sang trang Rails; thêm Angular router, forms libs, và ngx-bootstrap, mà chúng ta sẽ dùng để tạo và thao tác component Bootstrap dễ dàng. Vì vậy, chạy lệnh sau:

yarn add @angular/router @angular/forms html-loader css-loader ngx-bootstrap

Tuy nhiên, trước khi nhảy vào code component, có một vài khái niệm quan trọng chúng ta cần chỉ ra, bắt đầu với giải phẫu của component Angular.

Component Là Gì?

Trong Angular, component tồn tại để kết nối view của bạn với logic ứng dụng làm bằng TypeScript.

Nói cách khác, component giống như container cho tất cả logic view cần để hỗ trợ hoạt động của nó. Nó định nghĩa giá trị view sẽ trình bày và kiểm soát luồng của chúng. Nó tương đương với 'controller' trong các framework tương tự.

Để tạo component, tất cả bạn cần làm là định nghĩa class mới, implement interface OnInit, và annotate class với decorator @Component:

export class UserIndexComponent implements OnInit {
  constructor() { ... }
  ngOnInit() { ... }
}

@Component Và OnInit

Decorator @Component quan trọng vì nó đánh dấu class này là component Angular có thể nhận diện và cung cấp cấu hình metadata giúp Angular xử lý chúng về xử lý, khởi tạo, và sử dụng trong runtime.

Lấy các cấu hình metadata sau:

@Component({
  selector: "users",
  template: templateString,
})

Ở đây, selector nói cho Angular rằng giá trị được cung cấp là CSS selector nó có thể dùng để xác định directive hiện tại vào template; vâng, đó là cùng template được cung cấp trong thuộc tính metadata tiếp theo.

Interface OnInit, tuy nhiên, là tùy chọn, và là cách tốt để khởi tạo thứ gì đó trước khi component kết thúc vòng đời. Nó hoạt động như phương thức post-construct.

Dependency Injection (Tiêm Phụ Thuộc)

Angular là framework DI (Dependency Injection), đặc điểm tăng tính module và năng suất.

Phụ thuộc trong Angular có thể biến đổi từ service và repository của bạn đến bất kỳ object thông thường nào bạn cảm thấy phù hợp để tiêm ở nơi khác trong code.

Để biến class thành "injectable", bạn chỉ cần annotate nó với decorator @Injectable:

@Injectable({
  providedIn: "root",
})
export class UserService { ... }

providedIn chỉ ra injector nào sẽ cung cấp injectable bạn đang tạo. Giá trị root nói cho Angular rằng injector nên là application-level. Có nhiều hơn bạn có thể kiểm tra ở đây.

Để tiêm class vào component, ví dụ, bạn yêu cầu Angular làm nó trong constructor của component:

constructor(
  private userService: UserService,
) {}

Đơn giản như vậy!

Component Hoàn Chỉnh (The Finished Component)

Dưới đây, bạn có thể tìm thấy code listing cuối cho component User của chúng ta. Đặt nó vào index.component.ts, dưới thư mục javascript/hello_angular/app/.

import { Component, OnInit, TemplateRef } from "@angular/core";
import { FormGroup, FormBuilder } from "@angular/forms";
import { BsModalRef, BsModalService } from "ngx-bootstrap/modal";
import templateString from "./index.component.html";
import { UserService } from "../user.service";
import { User } from "../user.class";
@Component({
  selector: "users",
  template: templateString,
})
export class UserIndexComponent implements OnInit {
  users: User[];
  modalRef: BsModalRef;
  userForm: FormGroup;
  isNew: Boolean;
  constructor(public fb: FormBuilder, private userService: UserService, private modalService: BsModalService) {}
  public newUser(template: TemplateRef) {
    this.reset();
    this.modalRef = this.modalService.show(template);
  }
  public createUser() {
    this.userService.create(this.userForm.value).subscribe(() => {
      console.log("User created!");
      this.reset();
      this.modalRef.hide();
    });
  }
  public editUser(user, template: TemplateRef) {
    this.isNew = false;
    this.userForm = this.fb.group({
      id: [user.id],
      name: [user.name],
      age: [user.age],
      address: [user.address],
    });
    this.modalRef = this.modalService.show(template);
  }
  public updateUser() {
    const { id } = this.userForm.value;
    this.userService.update(id, this.userForm.value).subscribe(() => {
      console.log("User updated!");
      this.reset();
      this.modalRef.hide();
    });
  }
  public deleteUser(id) {
    if (confirm("Are you sure?")) {
      this.userService.delete(id).subscribe(() => {
        console.log("User deleted!");
        this.reset();
      });
    }
  }
  ngOnInit() {
    this.reset();
  }
  public reset() {
    this.isNew = true;
    this.userService.getUsers().subscribe((users) => {
      this.users = users;
    });
    this.userForm = this.fb.group({
      id: [""],
      name: [""],
      age: [""],
      address: [""],
    });
  }
}

Mảng users sẽ giữ dữ liệu bảng hiện tại được liệt kê trên màn hình và lấy từ phương thức reset mà, lần lượt, gọi Rails API của chúng ta qua UserService (sẽ được tạo).

userForm chỉ là tham chiếu giúp tạo và cập nhật user vì cùng form sẽ dùng cho cả hai operation. isNew cũng giúp với việc đó, xác định luồng nào chúng ta đang ở tại thời điểm.

Ở đây, chúng ta có phương thức tương đương CRUD cho mỗi operation. Mỗi cái gọi phương thức UserService tương ứng để commit process trong Rails API.

Chúng ta cũng cần thiết lập module HTML để chuyển template sang HTML (chúng ta sẽ thấy thêm về module sớm). Vì vậy, mở tệp html.d.ts trong cùng thư mục và thêm:

declare module "*.html" {
  const content: string;
  export default content;
}

Service Và Model Angular

Hãy chuyển sang tạo UserService của Angular. Angular là framework, giống như Rails. Vì vậy, có nghĩa là ổn để tuân theo quy tắc của họ ngay cả khi điều này nghĩa là có model trùng lặp (hoặc rất tương tự), ví dụ.

Model Là Gì?

Model Angular là object đơn giản giữ các thuộc tính dữ liệu có ý nghĩa cùng nhau (tức là chúng đại diện cho mảnh ngắn gọn của domain). Chúng giống như bất kỳ model nào trong hầu hết ngôn ngữ và framework.

Nó giúp rất nhiều khi dữ liệu tập trung ở một nơi, thay vì nhân bản nó khắp code như chúng ta làm với model user:

export class User {
  constructor(public id: number, public name: string, public age: number, public address: string) {}
}

Nhớ rằng đây là TypeScript, vì vậy thuộc tính model của bạn phải luôn có kiểu được định nghĩa.

Tạo tệp mới tên user.class.ts dưới thư mục javascript/hello_angular/app/user/ và đặt code trên vào.

Service Là Gì?

Service là khái niệm rộng, nhưng chúng ta có thể hiểu chúng là object được định nghĩa rõ ràng và có mục đích. Chúng giúp component với logic phức tạp hơn, phục vụ họ với dữ liệu đã được xử lý và biến đổi, thường đến từ service bên ngoài hoặc database.

Service không cần annotation hoặc interface cụ thể; bạn chỉ tạo class và làm cho nó injectable, như chúng ta đã thấy. Sau đó, bạn có thể tiêm nó vào component.

Observable Services (Service Quan Sát)

Một tính năng thú vị khác của Angular là nó cho phép bạn dùng RxJS với class của bạn.

Ví dụ, HTTP client mặc định của Angular, cùng cái chúng ta sẽ dùng để lấy thông tin từ service bên ngoài, trả về RxJS Observables. Đây là lý do, khi bạn gọi bất kỳ phương thức UserService nào trong user component, bạn có thể subscribe vào kết quả Observable:

this.userService.getUsers().subscribe((users) => {
  this.users = users;
});

Lưu ý nếu bạn không quen với RxJS, tôi khuyên mạnh một đọc nhanh tài liệu của nó; nó không khó lắm! ;)

Lại lần nữa, trong thư mục javascript/hello_angular/app/user/, tạo tệp khác tên user.service.ts. Đây là nội dung:

import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { map } from "rxjs/operators";
import { Observable } from "rxjs";
import { User } from "./user.class";
@Injectable({
  providedIn: "root",
})
export class UserService {
  constructor(private http: HttpClient) {}
  httpOptions = {
    headers: new HttpHeaders({
      "Content-Type": "application/json",
    }),
  };
  getUsers(): Observable {
    return this.http.get("/users.json").pipe(
      map((users: User[]) =>
        users.map((user) => {
          return new User(user.id, user.name, user.age, user.address);
        })
      )
    );
  }
  create(user): Observable {
    return this.http.post("/users.json", JSON.stringify(user), this.httpOptions);
  }
  update(id, user): Observable {
    return this.http.put("/users/" + id + ".json", JSON.stringify(user), this.httpOptions);
  }
  delete(id) {
    return this.http.delete("/users/" + id + ".json", this.httpOptions);
  }
}

Bạn có thể nhận ra sự tương đồng giữa cái này và component chúng ta vừa tạo? Điều này là vì chúng ta cần operation tương ứng để hỗ trợ cái trong component.

Lưu ý rằng HttpClient cũng phải được tiêm trong constructor của class, để chúng ta dùng nó cùng class.

Mỗi operation làm lời gọi HTTP đến Rails API, cái tự động tạo.

Views (Giao Diện)

Angular làm việc với template cho view. Template là loại HTML-and-JavaScript phân cấp hỗn hợp nói cho Angular cách render mỗi component.

Tuy nhiên, trước khi đi xa hơn với xây dựng view, hãy trước tiên hiểu cách Angular chia hệ thống template của nó.

Directive Angular (Chỉ Dẫn Angular)

Vì template Angular về bản chất là động, một vài directive được cần để dẫn dắt Angular qua đúng cách để render thứ.

Directive đơn giản là class với decorator @Directive, như component. Vâng, @Component kế thừa từ @Directive, vì vậy nó chính thức là directive.

Tuy nhiên, có hai loại khác: structural (cấu trúc) và attribute (thuộc tính) directive.

Structural Directives (Directive Cấu Trúc)

Directive này đại diện cho cấu trúc điều kiện và vòng lặp được chuyển từ JavaScript vào template Angular. Chúng giúp template động nhất có thể, như thể bạn đang lập trình trong code JavaScript vanilla. Lấy ví dụ sau:


  {{ user.name }}

Directive *ngFor nói cho Angular lặp qua mảng users và in tên mỗi user ra DOM.

Attribute Directives (Directive Thuộc Tính)

Chúng làm việc trực tiếp với giao diện hoặc hành vi của element. Lấy ví dụ sau:

Ở đây, chúng ta sửa đổi hành vi của form bằng cách có điều kiện thiết lập hàm submit của nó và dùng FormGroup của Angular để data-bind từng input form.

Data Binding (Ràng Buộc Dữ Liệu)

Tạo form với web framework có thể là nhiệm vụ rắc rối và dễ lỗi nếu nó không cung cấp data binding.

Angular hỗ trợ two-way data binding (ràng buộc dữ liệu hai chiều), nghĩa là bạn có thể kết nối trực tiếp mảnh template đến component và ngược lại.

Form trên là ví dụ tốt của sức mạnh data binding FormGroup. Nó tự động bind mỗi trường form đến object userForm được tạo trong component.

Trong phương thức editUser, ví dụ, bạn có thể thấy phiên bản ngược lại của binding, trong đó giá trị userForm được thiết lập trong component và sẽ phản ánh form trên view.

Xây Dựng View Index

Hãy chia nhỏ nội dung cho index.component.html thành hai phần. Đây là phần đầu:

User's Listing

A quick CRUD example of how to integrate Rails with Angular

Id Name Age Address Actions
{{ user.id }} {{ user.name }} {{ user.age }} {{ user.address }} |

Hầu hết là HTML thuần túy. Chúng ta sẽ không đi sâu vào class Bootstrap.

Phần quan trọng ở đây là directive ngFor trên hàng bảng. Nó giúp lặp qua mảng users (nhớ nó?) in từng thuộc tính ra output HTML qua toán tử {{ … }}.

Bất cứ khi nào bạn muốn thêm event DOM, như onClick, chỉ cần bọc tên event với ngoặc đơn và thêm hàm component nó sẽ gọi khi click.

Xây Dựng View Modal

Phần thứ hai liên quan đến nội dung modal, vì vậy thêm nó dưới phần trước:


  
  

Lưu ý chúng ta đang dùng thẻ <ng-template>, cho phép bạn neo element giữa HTML và Angular. Template ID đến ngay sau dấu #.

Trong form, cũng lưu ý chúng ta đang dùng biến component isNew để kiểm tra việc sử dụng hiện tại của form này liên quan đến tạo hay cập nhật user.

Cuối cùng, chúng ta cần tiêm toàn bộ ứng dụng hello_angular vào trang index.html.erb của Rails. Vì vậy, mở tệp này dưới thư mục views/users/ và thay đổi nội dung thành:

We're almost done...
<%= javascript_pack_tag 'hello_angular' %>

Module Angular

Bây giờ, chúng ta cần nói cho Angular nơi tìm thứ. Nó xảy ra trong cấu hình module.

Hãy bắt đầu bằng cách thêm nội dung vào app-bootstrap.module.ts:

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { ModalModule } from "ngx-bootstrap/modal";
@NgModule({
  imports: [CommonModule, ModalModule.forRoot()],
  exports: [ModalModule],
})
export class AppBootstrapModule {}

Điều này giới hạn ở component Bootstrap chúng ta kế thừa từ ngx-bootstrap. Component duy nhất chúng ta dùng cho lúc này là Bootstrap modal.

Sau đó, mở tệp app-routing.module.ts và thay đổi nội dung thành:

import { RouterModule, Routes } from "@angular/router";
import { NgModule } from "@angular/core";
import { UserIndexComponent } from "./user/index/index.component";
const appRoutes: Routes = [
  { path: "users", component: UserIndexComponent },
  { path: "", redirectTo: "/users", pathMatch: "full" },
];
@NgModule({
  imports: [RouterModule.forRoot(appRoutes, { scrollPositionRestoration: "enabled" })],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Điều này sẽ đảm bảo Angular match đúng component User khi path /users được gọi.

Và, cuối cùng, đăng ký tất cả trong class AppModule chính. Mở tệp app.module.ts và chắc chắn nó trông như sau:

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { HttpClientModule } from "@angular/common/http";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { AppComponent } from "./app.component";
import { AppRoutingModule } from "./app-routing.module";
import { AppBootstrapModule } from "./app-boostrap.module";
import { UserIndexComponent } from "./user/index/index.component";
@NgModule({
  declarations: [AppComponent, UserIndexComponent],
  imports: [HttpClientModule, AppRoutingModule, BrowserModule, FormsModule, ReactiveFormsModule, AppBootstrapModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Ở đây, mọi thứ được map. Từ form, HTTP client và user component đến config Bootstrap module, và routing.

Hoàn Thiện Config

Trước khi nhảy vào test, chúng ta cần hoàn thiện một vài thứ, bắt đầu với tệp app.component.ts:

import { Component } from "@angular/core";
@Component({
  selector: "hello-angular",
  template: "",
})
export class AppComponent {
  name = "Angular!";
}

Component app chính cần biết cách route path, vì vậy RouterOutlet sẽ làm việc.

Sau đó, chúng ta cần chắc chắn Webpacker hiểu phần mở rộng HTML chúng ta đang làm việc. Với điều này, mở tệp webpacker.yml và, dưới thư mục /config, tìm section extensions và thêm item sau:

- .html

Webpacker chỉ nhận diện TypeScript loader tích hợp sẵn mặc định với Angular. Chúng ta cần xử lý HTML, đó là lý do chúng ta trước cài dependency html-loader. Để thiết lập nó, mở tệp environment.js, dưới thư mục config/webpack, và thêm config loader sau:

environment.loaders.append("html", {
  test: /\.html$/,
  use: [
    {
      loader: "html-loader",
      options: { minimize: true },
    },
  ],
});

Cuối cùng, để ngăn service Angular nhận lỗi trên lời gọi HTTP, chúng ta cần tắt kiểm tra CSRF token do Rails thực hiện. Với điều này, mở tệp application_controller.rb, dưới thư mục app/controllers, và thay đổi nội dung thành:

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

Testing (Kiểm Thử)

Xong! Nó trông hơi rắc rối vì thiết lập yêu cầu nhiều tùy chỉnh, nhưng kết quả đáng giá.

Để test, lưu mọi thứ, và khởi động server bằng lệnh rails s.

Sau đó, vào trình duyệt và gõ địa chỉ https://localhost:3000/users. Tiến hành và chơi với ứng dụng web CRUD.

Kết Luận

Đã là con đường dài để get CRUD này lên và chạy. Sau lần thử đầu tiên, bạn sẽ thấy mọi thứ dễ dàng hơn cho dự án tương lai. Tôi hy vọng dự án này giúp thiết lập điểm xuất phát cho những bạn muốn bắt đầu dự án nhanh bằng cách kết hợp cả hai tech.

Mặc dù chúng ta không có dự án scaffolding mã nguồn mở để giúp, chúng ta dựa vào nỗ lực của nhau để có tài liệu như vậy. Bây giờ, đến lượt bạn; fork dự án (hoặc tạo từ đầu) và bắt đầu tùy chỉnh.

Kho GitHub cho ví dụ này có thể tìm thấy ở đây. Chúc vui vẻ!