# 开发一个 Rss 阅读器 02 - 建立模型和基本的页面

本来都快鸽了，不过还是决定继续，毕竟我的确需要一个 RSS 阅读器。从这篇文章开始，正式进入开发迭代的阶段。我的计划是先做简陋的版本，先用起来，然后再慢慢改进。

## 建立应用

我选择使用 replit.com 来免费托管应用，为了一个自用的 rss 阅读器，自己去购买 vps 建立服务什么的，太不划算了。非常幸运的是 replit 直接支持建立 Rails 类型的应用。

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1666971708337/7E_p8LeZv.png align="left")

如果你也想深度，可以自己在 repl 上面建立，或者 [fork 我的项目](https://replit.com/@greatghoul/RSS-Reader)。

## 建立模型

初期，我需要的三个实体如下

分类
- 名称

订阅
- 名称
- 订阅地址
- 归属的分类

文章
- 标题
- 链接
- 发布时间
- 阅读时间
- 内容
- 归属的订阅

首先，利用 rails 的 generator，生成一下基础的框架，包括 controller, model, form, json 什么的。

```bash
rails g scaffold Category name
rails g scaffold Channel title description link xml_link fetched_at:datetime category:belongs_to
rails g scaffold Item title description content link published_at:datetime read_at:datetime channel:belongs_to
```

最后再招待一下  db:migrate

```
rails db:migrate
```

这些 model 会自动生成一些关联关系，然后再手动补充一些必要的关系

```ruby
class Category < ApplicationRecord
  has_many :channels # ←---
end

class Channel < ApplicationRecord
  belongs_to :category
  has_many :items # ←---
end
```

## 简单的页面导航

将内容列表页面设置为网站首页，然后给所有页面添加一下基本的导航，方便在不同页面之间跳转

`config/routes.rb`

```ruby
Rails.application.routes.draw do
  # ...
  root "items#index"
end
```

`app/views/layouts/application.html.erb`

```
<body>
    <nav>
      <%= link_to "Items", items_path %>
      <%= link_to "Categories", categories_path %>
      <%= link_to "Channels", channels_path %>
    </nav>

    ...
<body>
```

这样网站打开后就是下面这个样子（没有数据）

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1666918211058/S45b1Dm9X.png align="left")

## 支持建立订阅

分类只有一个字段，暂时不需要什么修改，直接先建几个分类测试一下 。

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1666918067947/D-_f7-PQj.png align="left")

接下来访问 https://rss-reader.greatghoul.repl.co/channels/new 可以看到非常粗糙的表单页面

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1666916554820/boZPIsbpK.png align="left")

这里面有两个表单字段需要处理，一个是最后拉取时间，我不需要手工维护这个字段，直接删除，另一个是归属的分类，简单需要做成下拉框。

`app/views/channels/_form.html.erb`

```
  <div>
    <%= form.label :category_id, style: "display: block" %>
    <%= form.collection_select :category_id, Category.all, :id, :name %>
  </div>
```

![Snapshot.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1666917321354/f__FOsVUw.png align="left")

这里先不考虑自动根据 rss 链接获取订阅的标题等信息的问题。

## 下一步

下一步，我打算实现拉取订阅中文章的功能（文章列表是现成的，只需要小修改一下即可），然后再已读未读的功能，这样就可以简单的投入使用了。

