前端学Ruby:全栈论坛(地宫)项目一

简介: 前端学Ruby:全栈论坛(地宫)项目一

本来想做 buddha(菩萨)论坛的,发现自己参考的项目太难实现,猝

笔者回炉重修了一番,正好发现了 realworld,遂决定将 realworld 项目代替原先的 buddha 项目,还是要量力而行,不要一意孤行(项目规划太大,浪费太多时间学习)

先介绍一下 realworld 项目

源码:https://github.com/gothinkster/realworld

demo:https://demo.realworld.io/#/

UI:https://github.com/gothinkster/conduit-bootstrap-template

页面分析:https://www.jianshu.com/p/6014a9fefabd

从页面角度讲,只有七个页面,即

  • 首页(index)
  • 文章详情页(article)
  • 登录页(login)
  • 注册页(register)
  • 写文章页(editor)
  • 设置页(settings)
  • 个人页(profile)

接口方面和数据结构直接看 文档 就好,不说虚的,这个项目有19个接口,19个接口放其他语言要做多久?不知道,但 Ruby 应该花不了多少时间

介于此项目是个全栈项目,遂会前后端穿插地写,项目名我起好了:地宫(Underground Palace)

文章目录

搭建项目并部署

使用脚手架创建 article

穿上 bootstrap

新增fontawesome

device 用户体系

devise-i18n国际化

设置页

个人页

模型建立

查询功能

订阅功能

分页功能

再次部署

logo设计

后记

搭建项目并部署

我们先新建项目

rails new underground-palace
cd list

然后去 config/routes.rb 中修改根目录:

Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
  # Defines the root path route ("/")
  # root "articles#index"
  root "rails/welcome#index"
end

我们通过 fly.io 来部署我们的服务,对其不过多介绍,具体可看上篇文章——前端学Ruby:唐诗项目部署优化

fly launch # 创建
fly deploy # 部署
fly open # 打开刚刚部署的项目

fly launch

此时访问 https://underground-palace.fly.dev/ (这里我们的 underground 少写了一个字母,无伤大雅,后续已修正)就能看到刚还在本地新建的项目,是不是很快,有点意想不到的感觉

使用脚手架创建 article

rails 的一个特点是一个命令就做很多事情,例如接下来我们要用 rails generate scaffold 完成 article 的增删改查

rails g scaffold article title:string description:string body:text 
rails db:migrate # 数据迁入

并且修改config/routes.rb

Rails.application.routes.draw do
  resources :articles
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
  # Defines the root path route ("/")
  root "articles#index"
  # root "rails/welcome#index"
end

如此,用脚手架搭建的文章的增删改查就完成了,是不是很快

增删改查

穿上 bootstrap

realworld 项目是基于 bootstrap 的,我们需要下载 bootstrap 的 gem

这里需要做一下说明,像 bootstrap-sass gem 是基于 bootstrap 3 的样式,bootstrap gem 是最新版的 boostrap,也可以理解为 bootstrap 3 及一下可使用 bootstrap-sass,反之则用 boostrap

因为 realworld 是基于 bootstrap4.0.0,所以下载时我们需要先设定好版本。按照 readme 的步骤,在 gemfile 文件中引入 boostrapjquery-rails 包,再新增 common/footercommon/header 页面,将模板代码放进去

但是 readlworld 所提供的 bootstrap 和 线上版本 有差异,并不是直接引用能用(后续看到文档中有现成的 模板,但不知道有没有坑)

既然选择了做用 bootstrap 来做UI,索性用最新的 bootstrap5

我们不按照 gem 方式引入 bootstrap,用 cssbundling-rails jsbundling-rails 来构建资源

bundle add cssbundling-rails jsbundling-rails

查找我们与 css 相关的构建命令

rails | grep css

查看css

同理查看我们与 javascript 构建相关的命令

rails | grep javascript

我们下载 bootstrap,基于 yarn

rails css:install:bootstrap

下载 esbuild,也是基于yarn下载,

rails javascript:install:esbuild

但是报错 Could not resolve "app/javascript/*.*"

window中下载esbuild报错

不用慌,去package.json 修改 build 中的配置,将esbuild app/javascript/*.* --bundle --sourcemap... 改成 esbuild app/javascript/application.js --bundle --sourcemap...

并执行 npm run build 执行代码,当然,有些文件需要隐藏的这里不做过多描述

当能 build 成功后,我们开发就是用bin/dev 命令来开发

但因为笔者使用的是 window 系统,所以会因此报错:

unset为linux命令,报错

unset 不是 window 的命令,所以我们要改造,前往根目录下的 Procfile.dev 修改:

web: set "PORT=" && rails s
css: yarn build:css --watch
js: yarn build --watch

此时执行 /bin/dev 就能启动我们的项目了,其以上代码是启动 rails 服务,css 和 js 都是通过 yarn build 打包后监听(watch)变化,所以能做到热更新

新增fontawesome

按照好 bootstrap 后还不够,还需要安装图标,例如我们常用的fontawesome

首先安装 Font Awesome:

yarn add @fortawesome/fontawesome-free

然后在 config/initializers/assets.rb 添加以下内容:

Rails.application.config.assets.paths << Rails.root.join('node_modules/@fortawesome/fontawesome-free/webfonts')

最后在 app/assets/stylesheets/application.sass.scss 添加以下内容:

$fa-font-path: ".";
@import "@fortawesome/fontawesome-free/scss/fontawesome.scss";
@import "@fortawesome/fontawesome-free/scss/solid.scss";

接着就是把具体的 articlesarticles#showarticles#new页面的模板样式补充好

用户体系

我们使用 devise 来做我们的登录注册

安装  devise gem 包

bundle add devise

运行以下命令生成 Devise 文件

rails g devise:install

创建一个用户模型(例如User),并运行以下命令生成 Devise 所需要的视图和控制器:

rails g devise user

运行数据库迁移以创建 Devise 所需要的表

rails db:migrate

如此这般,登录注册忘记密码等一系列 CRUD 就做好了,我们只需要在 header.html.erb 中修改配置,将未登录时显示登录注册样式即可,即

...
<% if !current_user %>
        <!-- 未登录 -->
        <div class="col-md-3 text-end">
          <%= link_to '注册', new_user_registration_path, class: 'btn btn-outline-primary me-2' %>
          <%= link_to '登入', new_user_session_path, class: 'btn btn-primary' %>
        </div>
<% else %>
 <!-- 登录 -->
<% end %>
...

默认情况下,我们是看不到 devise 的视图和控制器的,因为我们要修改 UI,所以将视图释放出来:

rails g devise:views

前往视图层,修改views/devise/registrations/new.html.erb (注册页)和views/devise/session/new.html.erb(登录页)的样式

默认情况下,注册、登录的路由是users/sign_upusers/sign_in,和传统意义上的注册、登录路由不符,这里做一下映射,前往config/routes.rb中修改:

Rails.application.routes.draw do
  - devise_scope :user
  + devise_scope :user do
  +   get '/login' => 'devise/sessions#new'
  +   get '/register' => 'devise/registrations#new'
  + end
 ...
end

并前往views/common/_header.html.erb 中修改代码:

<!-- 未登录 -->
<div class="col-md-3 text-end">
  <%= link_to '注册', register_path, class: 'btn btn-outline-primary me-2' %>
  <%= link_to '登入', login_path, class: 'btn btn-primary' %>
</div>

静态页面放进后,现在我们要考虑的是将其动态化,首先改造的是注册页面,我们用form_for 来做表单,这里需要注意的是,在 devise 默认的字段里没有 username,我们需要加上

创建一个 migration 文件,用于向 User 模型添加 username 字段

rails g migration AddUsernameToUser username:string:uniq

uniq表示唯一

将这个 migration 迁移至数据库

rails db:migrate

models/user.rb 中新增对 username 的验证

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  validates :username, presence: true, uniqueness: { case_sensitive: false }, length: { minimum: 3, maximum: 25 }
end
  • presence: true 验证:该属性必须存在(不能为 nil 或空白字符串)
  • uniqueness: { case_sensitive: false } 验证:该属性的值必须是唯一的(即数据库中不存在相同的值)。此外,该验证规则将忽略大小写,因此类似的两个字符串,例如 abcABC,将被认为是相等的
  • length: { minimum: 3, maximum: 25 } 验证:该属性的长度必须介于 3 到 25 个字符之间

修改注册页面视图,新增用户名样式

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  ...
  <div class="form-group mb-3">
    <%= f.text_field :username, autofocus: true, autocomplete: "username", 
    class: "form-control form-control-lg",
    placeholder: "用户名" %>
  </div>
  ...
<% end %>

在改造时,我们还需要生成 devise 的控制器,让表单在提交时前往正确的控制器处(因为我们定制了登录注册路径,而不是用默认的,所以还要改造)

rails g devise:constroller -c # 生成所有 devise 的控制器

再在 config/routes.rb 中修改

...
 devise_for :users, path: "", path_names: {
    sign_in: "login",
    sign_out: "logout",
    sign_up: "register" 
  }, controllers: {
    registrations: "users/registrations",
    sessions: "users/sessions",
  }
  devise_scope :user do
    get '/login' => 'devise/sessions#new'
    get '/register' => 'devise/registrations#new'
  end
  ...

如此,注册页面就改造完了,继续改造登录页面

devise-i18n国际化

当我们做完登录页之后,提示报错信息还都是英文的,这次需要引入 i18n 来做中文提示

老规矩,先安装 devise-i18n gem

bundle add devise-i18n

config/application.rb 文件中添加如下代码:

config.i18n.default_locale = "zh-CN"

执行 devise:i18n 生成中文命令

rails generate devise:i18n:locale zh-CN

再去config/locales/devise.zh-CN.yml 中修改不满意的翻译,如此就完成了国际化

如此我们已经完成了5个页面,即首页、文章详情页、登录页、注册页、写文章页,还剩下设置页和个人页

设置页

如果说 article 和 user 是通过命令行来生成的,那么接下来的两个页面(设置、个人页),就是我们正常开发时的开发流程

先创建一个 Settings 控制器:

rails g controller Settings index

config/routes.rb 中新增一个 "seetings" (单数资源)资源路由,开放 show 和 update :

resource :settings, only: [:show, :update]

创建 app/views/settings/index.html.erb 页面,加上 bootstrap 样式,settings 的静态页面就能访问了

看静态页面我们就知道,users 数据中我们还缺少头像(avatar)和简介(bio),所以我们需要在 users 表中新增两个字段

生成一个迁移文件,该文件添加 avatar 和 bio 列到 users 表中

rails g migration AddAvatarAndBioToUsers avatar:string bio:string

运行 rails db:migrate 修改数据库中的表

rails db:migrate

接着我们前往 settings_controller.rb  控制器,修改为后续渲染页面

class SettingsController < ApplicationController
    before_action :authenticate_user!
    before_action :set_user
    def show
    end
    def update
       if @user.update(user_params)
            # 后续跳转到个人设置页面
            redirect_to root_path
            flash[:notice] = '修改成功'
        else
            render :show
        end
    end
    private
    def set_user
      @user = current_user
    end
    def user_params
        params.require(:user).permit(:username, :email, :avatar, :bio)  
    end
end

同样,视图也要修改,删除更改密码一栏,为什么呢?因为 devise 中修改密码,需要输入原密码,是很麻烦的,笔者尝试了一下,放弃了

个人页

我们继续做个人页,也是我们的最后一个页面,虽然还有很多细节(比如评论、点赞文章、收藏文章等逻辑),但是从页面的角度讲,这就是最后一个页面了

先建立控制器

rails g controller profile

config/routes.rb 处,新增一个路由映射

get '/:name', to: 'profile#show', as: :profile

前往views/common/_header.html.erb 处,修改原来的 username 视图

<li class="nav-item">
    <%= link_to profile_path(current_user.username), class: "nav-link px-2" do %>
      <%= image_tag current_user.avatar, alt: "avatar", class: "user-pic" %>
      <%= current_user.username %>
    <% end %>
  </li>

然后我们去 view/profile/show.html.erb 写好我们的静态页面,7个页面就此完成,但这只完成了一半。接下来,我们要对页面进行改造,加上文章评论、点赞/取消点赞、关注/取消用户等等功能

如此,已经耗尽一天功夫,休息一晚,明天再战


相关文章
|
1月前
|
Cloud Native 前端开发 JavaScript
前端开发者必看:不懂云原生你就OUT了!揭秘如何用云原生技术提升项目部署与全栈能力
【10月更文挑战第23天】随着云计算的发展,云原生逐渐成为技术热点。前端开发者了解云原生有助于提升部署与运维效率、实现微服务化、掌握全栈开发能力和利用丰富技术生态。本文通过示例代码介绍云原生在前端项目中的应用,帮助开发者更好地理解其重要性。
85 0
|
1月前
|
监控 前端开发 数据可视化
3D架构图软件 iCraft Editor 正式发布 @icraft/player-react 前端组件, 轻松嵌入3D架构图到您的项目,实现数字孪生
@icraft/player-react 是 iCraft Editor 推出的 React 组件库,旨在简化3D数字孪生场景的前端集成。它支持零配置快速接入、自定义插件、丰富的事件和方法、动画控制及实时数据接入,帮助开发者轻松实现3D场景与React项目的无缝融合。
115 8
3D架构图软件 iCraft Editor 正式发布 @icraft/player-react 前端组件, 轻松嵌入3D架构图到您的项目,实现数字孪生
|
2月前
|
JavaScript 前端开发 Docker
前端全栈之路Deno篇(二):几行代码打包后接近100M?别慌,带你掌握Deno2.0的安装到项目构建全流程、剖析构建物并了解其好处
在使用 Deno 构建项目时,生成的可执行文件体积较大,通常接近 100 MB,而 Node.js 构建的项目体积则要小得多。这是由于 Deno 包含了完整的 V8 引擎和运行时,使其能够在目标设备上独立运行,无需额外安装依赖。尽管体积较大,但 Deno 提供了更好的安全性和部署便利性。通过裁剪功能、使用压缩工具等方法,可以优化可执行文件的体积。
151 3
前端全栈之路Deno篇(二):几行代码打包后接近100M?别慌,带你掌握Deno2.0的安装到项目构建全流程、剖析构建物并了解其好处
|
1月前
|
前端开发 测试技术
前端工程化的分支策略要如何与项目的具体情况相结合?
前端工程化的分支策略要紧密结合项目的实际情况,以实现高效的开发、稳定的版本控制和顺利的发布流程。
28 1
|
1月前
|
前端开发 Unix 测试技术
揭秘!前端大牛们如何高效管理项目,确保按时交付高质量作品!
【10月更文挑战第30天】前端开发项目涉及从需求分析到最终交付的多个环节。本文解答了如何制定合理项目计划、提高团队协作效率、确保代码质量和应对项目风险等问题,帮助你学习前端大牛们的项目管理技巧,确保按时交付高质量的作品。
41 2
|
2月前
|
JavaScript 前端开发 测试技术
前端全栈之路Deno篇(五):如何快速创建 WebSocket 服务端应用 + 客户端应用 - 可能是2025最佳的Websocket全栈实时应用框架
本文介绍了如何使用Deno 2.0快速构建WebSocket全栈应用,包括服务端和客户端的创建。通过一个简单的代码示例,展示了Deno在WebSocket实现中的便捷与强大,无需额外依赖,即可轻松搭建具备基本功能的WebSocket应用。Deno 2.0被认为是最佳的WebSocket全栈应用JS运行时,适合全栈开发者学习和使用。
139 7
|
2月前
|
前端开发 JavaScript 中间件
前端全栈之路Deno篇(四):Deno2.0如何快速创建http一个 restfulapi/静态文件托管应用及oak框架介绍
Deno 是由 Node.js 创始人 Ryan Dahl 开发的新一代 JavaScript 和 TypeScript 运行时,旨在解决 Node.js 的设计缺陷,具备更强的安全性和内置的 TypeScript 支持。本文介绍了如何使用 Deno 内置的 `Deno.serve` 快速创建 HTTP 服务,并详细讲解了 Oak 框架的安装和使用方法,包括中间件、路由和静态文件服务等功能。Deno 和 Oak 的结合使得创建 RESTful API 变得高效且简便,非常适合快速开发和部署现代 Web 应用程序。
125 2
|
2月前
|
JavaScript 前端开发 Serverless
前端全栈之路Deno篇:Deno2.0与Bun对比,谁更胜一筹?可能Deno目前更适合serverless业务
在前端全栈开发中,Deno 2.0 和 Bun 作为新兴的 JavaScript 运行时,各自展现了不同的优势。Deno 2.0 重视安全性和多平台兼容性,尤其是对 Windows 的良好支持和原生 TypeScript 支持;而 Bun 则以卓越的性能和简便的开发体验著称,适合快速迭代的小型项目。两者在不同场景下各具特色,Deno 更适合企业级应用和serverless,Bun 则适用于追求速度的项目。
256 1
|
2月前
|
前端开发 安全 API
前端全栈之路Deno篇(三):一次性搞懂和学会用Deno 2.0 的权限系统详解和多种权限配置权限声明方式
本文深入解析了 Deno 2.0 的权限系统,涵盖主包和第三方包的权限控制机制,探讨了通过命令行参数、权限 API 和配置文件等多种权限授予方式,并提供了代码示例和运行指导,帮助开发者有效管理权限,提升应用安全性。
|
2月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
190 2