Item
và Group
cùng với các file migration tương ứng:$ rage g model Item$ rage g model Group
rage --tasks
.# app/models/group.rbclass Group < ApplicationRecord has_many :itemsend
# app/models/item.rbclass Item < ApplicationRecord belongs_to :groupend
# db/migrate/20250401110130_create_groups.rbclass CreateTodoGroups < ActiveRecord::Migration[8.0] def change create_table :groups do |t| t.string :name, null: false t.timestamps end endend
# db/migrate/20250401110130_create_items.rbclass CreateItems < ActiveRecord::Migration[8.0] def change create_table :items do |t| t.string :content, null: false t.boolean :is_completed, null: false, default: false t.references :group, index: true, null: false t.timestamps end endend
# db/seeds.rbItem.create!( group: Group.new(name: "New Year's resolutions"), content: "Build fast APIs with Rage", created_at: Time.now.beginning_of_year)
$ rage db:create && rage db:migrate && rage db:seed
# config/routes.rbRage.routes.draw do scope path: "api/v1" do resources :items, only: %i[index] endend
# app/controllers/items_controller.rbclass ItemsController < ApplicationController def index endend
alba
vào Gemfile:gem 'alba'
# config/initializers/alba_inflector.rbAlba.inflector = :active_support
# app/resources/application_resource.rbclass ApplicationResource include Alba::Resource root_key :data, :data transform_keys :lower_camelend
# app/resources/group_resource.rbclass GroupResource < ApplicationResource attributes :id, :name has_many :itemsend
# app/resources/item_resource.rbclass ItemResource < ApplicationResource attributes :content, is_completed: :Booleanend
class ItemsController < ApplicationController def index groups = Group.includes(:items).all render json: GroupResource.new(groups) endend
$ rage s
includes(:items)
giúp giảm thiểu truy vấn lặp lại khi lấy nhóm và các mục tương ứng.config/routes.rb
:mount Rage::OpenAPI.application, at: "/publicapi"
class ItemsController < ApplicationController # Get all Todo items grouped by their parent groups. # @response Array<GroupResource> def index groups = Group.includes(:items) render json: GroupResource.new(groups) endend
class ItemsController < ApplicationController # Get all Todo items grouped by their parent groups. # @param limit? Number of items per page # @param offset? The offset of the first item to return # @response Array<GroupResource> def index limit = params[:limit] || 10 offset = params[:offset] || 0 groups = Group.includes(:items).limit(limit).offset(offset) render json: GroupResource.new(groups) endend
Rage.routes.draw do scope path: "api/v1" do resources :items, only: %i[index create] endend
class ItemsController < ApplicationController # Create a new Todo item. # @request { item: { content: String, group_id: Integer } } # @response ItemResource def create item = Item.create!(item_params) render json: ItemResource.new(item) end
private
def item_params params.fetch(:item).slice(:content, :group_id) endend
mount Rage::Cable.application, at: "/cable"
# app/channels/items_channel.rbclass ItemsChannel < Rage::Cable::Channel def subscribed stream_from "todo-items" endend
class ItemsController < ApplicationController # Create a new Todo item. # @request { item: { content: String, group_id: Integer } } # @response ItemResource def create item = Item.create!(item_params) render json: ItemResource.new(item) Rage::Cable.broadcast("todo-items", { action: "new-item", data: item }) endend
Test Case | Kết Quả |
---|---|
Hello World | Rage vượt trội với độ trễ thấp hơn nhiều |
Waiting on I/O | Xử lý bất đồng bộ tốt hơn, tiết kiệm thời gian chờ |
ActiveRecord | Truy xuất dữ liệu nhanh và ổn định hơn |