Basic Subdomains in Ruby on Rails
Bài đăng này đã không được cập nhật trong 6 năm
Subdomains(Tên miền phụ), chắc hẳn cụm từ này đã quá quen thuộc với bất cứ ai am hiểu công nghệ hiện nay. Tiên miền phụ khá hữu ích cho người dùng ở một số trường hợp khác nhau. Ví dụ, bạn xây dựng một dứng dụng blog đa người dùng. Mỗi người dùng nhận được blog của riêng họ. Việc có thể cung cấp cho mỗi người một tên miền phụ duy nhất cho phép bạn cung cấp người dùng không gian cá nhân của riêng họ.
Tuy vậy, đối với một số lập trình viên mới vào nghề cụm từ này còn khá mới mẻ, Trong bài viết này mình sẽ xây dưng một ứng dụng blog đơn giản có chứa tính năng này.
Rails Application Setup
Đầu tiên, chung ta cần chuẩn bị một số model để phục vụ mục đích lưu trữ dữ liệu cho subdomains
như sau:
- Blog: Mỗi một blog chứa nhiều bài đăng, đại diện cho 1 blog cụ thể và chứa thông tin miền phụ tương ứng
- Post: Chứa thông tin của một bài đăng cụ thể như tên, tiêu đề . .
Các lệnh chạy như sau:
rails g model Blog name subdomain
# Tạo ra model Blog gồm hai trường name và subdomain
rails g model Post title body:text blog:references
# Tạo ra model Post thuộc về một Blog, có hai trường title và body
rake db:migrate
# Lệnh thực thi của rails
Tiếp theo, chúng ta khởi tạo controller cho model tương ứng sẽ có blogs
và posts
controller.
Chạy các lệnh như sau:
rails g controller blogs index show
# Tạo ra controller blogs
rails g controller posts show
# Tạo ra controller posts
Ok rồi, tới đây là phần quan trong nhất, thay đổi cài đặt routes để ứng dụng có thể hứng được request từ tên miền phụ và hiểu được chúng.
Cơ bản sẽ có sự thay đổi dưới đây:
SubdomainsExample::Application.routes.draw do
resources :posts
resources :blogs
match '/', to: 'blogs#index', constraints: { subdomain: 'www' }, via: [:get, :post, :put, :patch, :delete]
match '/', to: 'blogs#show', constraints: { subdomain: /.+/ }, via: [:get, :post, :put, :patch, :delete]
root to: "blogs#index"
end
Trong đó:
- Hai dòng đầu là khai báo đường routes của hai controller
posts
vàblogs
ở tiên miền chính - Hai dòng sau định nghĩa việc chấp nhận tên miền phụ đi kèm với định dạng http://www.yourdomain.com
Tiếp theo chúng ta cần một số ít code trong applications
controller để lấy được blog tương ứng khi request tên miền phụ.
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :get_blog
private
def get_blog
blogs = Blog.where(subdomain: request.subdomain)
if blogs.count > 0
@blog = blogs.first
elsif request.subdomain != 'www'
redirect_to root_url(subdomain: 'www')
end
end
end
Nhìn đoạn code trên chắc hẳn chúng ta đã đoán ra được ý đồ.
- Trước khi request được server xử lý sẽ được phân loại riêng của tên miền phụ nào tương ứng.
- Nếu không tìm được tên miền phụ tương ứng sẽ điều hướng tới trang chủ
Tiếp theo, chúng ta cần một số khai báo cơ bản trong BlogsController
, đây là xử lý riêng cho từng blog nếu đã được chấp nhận từ phía server.
class BlogsController < ApplicationController
def index
@blogs = Blog.all
end
# Lấy toàn bộ blogs có trong hệ thống
def show
@posts = @blog.posts
end
# Lấy toàn bộ bài viết của một blog cụ thể
end
Tương tự như BlogsController
chúng ta cũng cần khai báo một chút code cho PostsController
class PostsController < ApplicationController
def show
@post = @blog.posts.find(params[:id])
# Lấy thông tin của bài post được chỉ định từ view
end
end
Tiếp theo, chúng ta cần một số code cho phần view blogs, code phần view khá dễ hiểu nên mình không giải thích gì thêm. app/views/layouts/application.html.erb:
<!DOCTYPE html>
<html>
<head>
<title>SubdomainsExample</title>
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= stylesheet_link_tag "http://yandex.st/bootstrap/3.0.2/css/bootstrap.min.css", media: "all" %>
<%= javascript_include_tag "http://yandex.st/bootstrap/3.0.2/js/bootstrap.min.js" %>
<%= csrf_meta_tags %>
</head>
<body>
<div class="container">
<%= yield %>
</div>
</body>
</html>
app/views/blogs/index.html.erb:
<h1>Blogs on this Server</h1>
<ul>
<% @blogs.each do |blog| %>
<li><%= link_to blog.name, root_url(subdomain: blog.subdomain) %></li>
<% end %>
</ul>
app/views/blogs/show.html.erb:
<h1><%= @blog.name %></h1>
<hr />
<% @posts.each do |post| %>
<h3><%= post.title %></h3>
<p><%= truncate post.body, length: 160 %></p>
<%= link_to "Read More", post %>
<% end %>
app/views/posts/show.html.erb:
<h1><%= @post.title %></h1>
<p>
<%= @post.body %>
</p>
Cuối cùng để có thể test được ứng dụng chúng ta cần tạo ra một số data demo. db/seeds.rb:
Blog.delete_all
Blog.create(id: 1, name: "My Example Blog", subdomain: "example")
Blog.create(id: 2, name: "Awesome Blog", subdomain: "awesome")
Post.delete_all
Post.create(id: 1, blog_id: 1, title: "An Example of a Post", body: "This is a perfect example of a blog post. Feel free to reference this example in your other applications. Note that the author of this blog post does not accept responsibility for the contents of this blog post.")
Post.create(id: 2, blog_id: 1, title: "Another Example of a Post", body: "This is yet another example of a blog post. This one is less perfect than the first one.")
Post.create(id: 3, blog_id: 2, title: "An Utterly Awesome Post", body: "This is a super awesome example of a really good blog post. You should...like...totally copy this!")
Post.create(id: 4, blog_id: 2, title: "Yet Another Utterly Post", body: "This is yet ANOTHER example of a super awesome blog post. You should totally copy this one as well!")
Chạy lệnh sau để tạo dữ liệu:
rake db:seed
Ok, mọi thứ đã xong chúng ta cùng thử thành quả xem sao. Kết quả của trang chủ blog:
Chúng ta có thể thấy trên trang chủ hiện có hai blogs cá nhân được khởi tạo ở tên miền chính. Bây giờ chúng ta xem chi tiết một blogs cá nhân xem sao.
Các bạn để ý nhé, tên miền phụ đã được thay đổi, trên trang này hoàn toàn là không gian riêng của blog cá nhân.
Mình tạm dừng ở đây nhé, các bạn thấy thật đơn giản phải không? Hy vọng bài viết sẽ giúp ích phần nào các bạn.
Thanks for reading !!!
All rights reserved