rails101再复盘-2

5-1 本章目标

  • 安装“会员系统”(使用 devise)
  • 在 navbar 安装登录/退出按钮
  • 只有登录了的使用者,才可以建立群组
  • 只有群组的建立者,才可以 编辑 / 删除群组

5-2 安装 devise gem

  • 先创建分支 git checkout -b ch04

  • 1: 安装登录系统
    Gemfile 新增一行 gem 'devise', 然后 bundle install

  • 2 : 产生会员系统的必要文件
    执行
    rails g devise:install
    rails g devise user
    rake db:migrate 之后 重开 rails s

  • 3: 在 groups_controller 限制 “新增讨论群”必须先登录

# app/controllers/groups_controller.rb

class GroupsController < ApplicationController
  before_action :authenticate_user! , only: [:new]
  • 4: git 存档

5-3 让这个网站有实际“登录”、“退出”的功能

让右上角的“登录”可以实际有:“登录” / “退出的效果”

  • 1: 修改 app/views/common/_navbar.html.erb
# app/views/common/_navbar.html.erb
-                <li> 
-                  <%= link_to("登录", '#') %>   
-                </li>
+                <% if !current_user %>
+                  <li><%= link_to("注册", new_user_registration_path) %> </li>
+                  <li><%= link_to("登录", new_user_session_path) %></li>
+                <% else %>
+                  <li class="dropdown">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+                        Hi!, <%= current_user.email %>
+                        <b class="caret"></b>
+                    </a>
+                    <ul class="dropdown-menu">
+                        <li> <%= link_to("退出", destroy_user_session_path, method: :delete) %> </li>
+                    </ul>
+                  </li>
+                <% end %>
  • 2: 修改 app/assets/javascripts/application.js
# app/assets/javascripts/application.js

//= require bootstrap/alert
+ //= require bootstrap/dropdown
  • 3: git 储存

5-4 让“群组”与“使用者”产生关联

  • 1: 新增 user_id 到 group 的 table 里
    执行 rails g migration add_user_id_to_group
    然后打开刚刚新增的 migration 档,修改让它长得像这样
# db/migrate/一串数字_add_user_id_to_group
class AddUserIdToGroup < ActiveRecord::Migration[5.0]
  def change
    add_column :groups, :user_id, :integer
  end
end

接着执行rake db: migrate

  • 2: 连结 user 与 group 的双向关系
    修改 app/models/user.rb 加入 has_many :groups
# app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:

  # :confirmable, :lockable, :timeoutable and :omniauthable

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :groups
end

修改 app/models/group.rb 加入 belongs_to :user

# app/models/group.rb
class Group < ApplicationRecord
  belongs_to :user
  validates :title, presence: true
end
  • 3: 在新增看板时,记录谁是群组的建立者
    修改 app/controllers/groups_controller.rb,在需要“登入验证”的 action 列表再加入 create。
# app/controllers/groups_controller.rb
class GroupsController < ApplicationController
  before_action :authenticate_user! , only: [:new, :create]

修改 app/controllers/groups_controller.rb,在 create 中,多加入一行 @group.user = current_user,变成以下内容:

# app/controllers/groups_controller.rb
  def create
    @group = Group.new(group_params)
    @group.user = current_user
    
    if @group.save
      redirect_to groups_path
    else
      render :new
    end
  end
  • 4 : git 储存

  • 5 : 修改 group 列表,将 user 的名字列上去
    修改 app/views/groups/index.html.erb 然后把 Creator 的信息加进去。(代码如下)

app/views/groups/index.html.erb
<div class="col-md-12">
  <div class="group">
    <%= link_to("New group", new_group_path, class: "btn btn-primary pull-right") %>
  </div>
  <table class="table table-hover">
    <thead>
      <tr>
        <td>#</td>
        <td>Title</td>
        <td>Description</td>
+       <td>Creator </td>
      </tr>
    </thead>
    <tbody>
      <% @groups.each do |group| %>
        <tr>
          <td>#</td>
          <td><%= link_to(group.title, group_path(group)) %></td>
          <td><%= group.description %></td>
+         <td> <%= group.user.email %> </td>
          <td>
              <%= link_to("Edit", edit_group_path(group), class: "btn btn-sm btn-default")%>
              <%= link_to("Delete", group_path(group),    class: "btn btn-sm btn-default",
                          method: :delete, data: { confirm: "Are you sure?" } )%>
          </td>
        </tr>
      <% end %>
    </tbody>
  </table>
</div>

做完之后,打开 http://localhost:3000/ 会发现,首页怎么爆炸了。
别担心,这是因为我们之前创造的“群组”都是“无主”的。只要把这些“无主”的群组,通通删掉就行了。

  • 6: 删除所有“无主”的群组
    执行 rails console
    然后输入 Group.delete_all
    输入 exit 退出 console然后再打开 http://localhost:3000/ 就正常了。

  • 7 : git 存档

5-5 只有群组的“创始者”可以“编辑”“删除”群组资讯

  • 1: 路人不应该可以看到“编辑”“删除”按钮
    根据逻辑 只有登入模式下
    而且还必须是群组“创始者”
    才能看得到这个两个按钮,否则路人是看不到的。
app/views/groups/index.html.erb
      <td>
+            <% if current_user && current_user == group.user %>
             <%= link_to("Edit", edit_group_path(group), class: "btn btn-sm btn-default")%>
             <%= link_to("Delete", group_path(group),    class: "btn btn-sm btn-default",
                         method: :delete, data: { confirm: "Are you sure?" } )%>
+            <% end %>
          </td>

重新刷新首页,路人现在就看不到按钮了。接着 git 保存。

  • 3: 路人不应该也可以“直接输入网址”去存取 edit / update / destroy action

除了将按钮对路人隐藏外,我们还要考虑到一个情形,假设这个路人是知道 Rails 规则的,那么他可能输入http://localhost:3000/groups/某笔数据的ID/edit 网址,就直接可以编辑数据。
我们也要在 controller 做权限判断,滤掉这种人。

首先,我们先限定 edit / update / destroy 这三个操作动作,必须要是“登入”的使用者才能存取。

# app/controllers/groups_controller.rb

class GroupsController < ApplicationController
    before_action :authenticate_user! , only: [:new, :create, :edit, :update, :destroy]
  • 4: 必须要是 group 拥有人,才能进入 edit,否则会被重导至首页,并显示错误信息。
    修改 app/controllers/groups_controller.rb 加入权限,如果不是“创始者”去存取,会显示没有权限的错误信息。
# app/controllers/groups_controller.rb
  def edit
    @group = Group.find(params[:id])

    if current_user != @group.user
      redirect_to root_path, alert: "You have no permission."
    end
  end

这样当其他人,试图输入http://localhost:3000/groups/某笔数据的ID/edit这样的网址,想要编辑数据,就会被挡住。

  • 5: 依样画葫芦的把“权限检查”的代码,套用到 update / destroy 上

  • 6: git 存档

  • 7: 制作find_group_and_check_permission

我们发现 edit、update、destroy 这三个 action 都有一样的代码,看起来有点冗。

 @group = Group.find(params[:id])

if current_user != @group.user
  redirect_to root_path, alert: "You have no permission."
end

其实我们可以透过把它包装成一个函式的方式 find_group_and_check_permission 去省略这段冗余代码。

打开 app/controllers/groups_controller.rb 在 private 下,新增一个 find_group_and_check_permission

# app/controllers/groups_controller.rb
  private

  def find_group_and_check_permission
    @group = Group.find(params[:id])

    if current_user != @group.user
      redirect_to root_path, alert: "You have no permission."
    end
  end

  def group_params
    params.require(:group).permit(:title, :description)
  end

end  

再修正 edit

# app/controllers/groups_controller.rb
  def edit
    find_group_and_check_permission
  end

修正 update

# app/controllers/groups_controller.rb
  def update

    find_group_and_check_permission

    if @group.update(group_params)
      redirect_to groups_path, notice: "Update Success"
    else
      render :edit
    end
  end

修正 destroy

# app/controllers/groups_controller.rb
  def destroy
    find_group_and_check_permission
    
    @group.destroy
    redirect_to groups_path, alert: "Group deleted"
  end
  • 8: 把 find_group_and_check_permission 挂到 before_action
    开发到这里你会发现一件事,find_group_and_check_permission 其实都是在这三个 action 的最前面开头执行的,所以你甚至可以这样写,把 find_group_and_check_permission 挂到 before_action
# app/controllers/groups_controller.rb
class GroupsController < ApplicationController

  before_action :authenticate_user! , only: [:new, :create, :edit, :update, :destroy]
  before_action :find_group_and_check_permission, only: [:edit, :update, :destroy]

然后再把 edit update destroy 里的 find_group_and_check_permission砍掉。变成这样:

# app/controllers/groups_controller.rb
  def edit
  end

  def update
    if @group.update(group_params)
      redirect_to groups_path, notice: "Update Success"
    else
      render :edit
    end
  end

  def destroy
    @group.destroy
    redirect_to groups_path, alert: "Group deleted"
  end
  • 9: git 存档

  • 10 : 修掉 show 里面的 Edit 按钮
    做到这里,我们还发现一个地方,我们漏了改,那就是 show.html.erb 上面,还有一个 Edit 按钮我们还没有拔掉。

app/views/groups/show.html.erb
  <div class="group">
    <% if current_user && current_user == @group.user %>
      <%= link_to("Edit", edit_group_path(@group), class: "btn btn-primary pull-right")%>
    <% end %>
  </div>
  • 11: git 存档




6-1 本章目标

可以在群组里面新增 / 编辑 / 删除文章
文章必须要有“内容”,否则不允许被发表

6-2 建立文章的架构

git checkout -b ch05

    1. 设计 Post 的 model 架构
      rails g model post content:text group_id:integer user_id:integer
      rake db:migrate
    1. 建立 Group / Post / User 三者间的关系
      Group has_many posts
# app/models/group.rb
class Group < ApplicationRecord
  belongs_to :user
  has_many :posts
  validates :title, presence: true
end

User has_many posts

# app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:

  # :confirmable, :lockable, :timeoutable and :omniauthable

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :groups
  has_many :posts
end

Post belongs_to User
Post belongs_to Group

# app/models/post.rb
class Post < ApplicationRecord
  belongs_to :user
  belongs_to :group
end
    1. git 存档
    1. 建立 Post Controller
      rails g controller posts
    1. 设立 routing
      修改 config/routes.rb
      resources :posts 加入 resources :groups 内。
# config/routes.rb

Rails.application.routes.draw do
  devise_for :users
  resources :groups do
    resources :posts
  end
  root 'groups#index'
end

之后 rake routes
然后你就会发现, routing 列表内产生了 /groups/:group_id/posts/new 这样的网址支援。

    1. git 存档
    1. 在 groups#show 新增 “发表文章”按钮,加入一行
# app/views/groups/show.html.erb    
  <%= link_to("Write a Post", new_group_post_path(@group), class: "btn btn-default pull-right")%>
    1. git 存档

6-3 实际发表文章

实际把文章发在群里面
使用者可以在群里面看到文章一览表

  • 1: 实作 new / create action
# app/controllers/posts_controller.rb
class PostsController < ApplicationController

  before_action :authenticate_user!, :only => [:new, :create]

  def new
    @group = Group.find(params[:group_id])
    @post = Post.new
  end

  def create
    @group = Group.find(params[:group_id])
    @post = Post.new(post_params)
    @post.group = @group
    @post.user = current_user

    if @post.save
      redirect_to group_path(@group)
    else
      render :new
    end
  end


  private

  def post_params
    params.require(:post).permit(:content)
  end

end
    1. 新增 app/views/posts/new.html.erb
# app/views/posts/new.html.erb
<h2 class="text-center">新增文章</h2>

<div class="col-md-4 col-md-offset-4">
  <%= simple_form_for [@group,@post] do |f| %>
    <div class="form-group">
      <%= f.input :content, input_html: { class: "form-control"} %>
    </div>
    <div class="form-actions">
      <%= f.submit "Submit", disable_with: "Submiting...", class: "btn btn-primary"%>
    </div>
  <% end %>
</div>
    1. 修改 groups_controller 中的 show action
# app/controllers/groups_controller.rb
  def show
    @group = Group.find(params[:id])
    @posts = @group.posts
  end
    1. 修改 groups/show.html.erb
      我们要修改app/views/groups/show.html.erb,让文章能够显示出来,在<%= @group.description %>下,我们多加了一个表格做这件事。
# app/views/groups/show.html.erb
...(略)
  <p><%= @group.description %></p>

+  <table class="table">
+    <thead>
+     <tr>
+        <th>文章内容</th>
+        <th>发表者</th>
+        <th>发表时间</th>
+      </tr>
+    </thead>
+    <tbody>
+      <% @posts.each do |post| %>
+        <tr>
+          <td><%= post.content %></td>
+          <td><%= post.user.email %></td>
+          <td><%= post.created_at %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
  • 5: 对 Post 加上 validation
    这时候我们发现,刚刚有文章不小心没填内容,就发出去变成空的。
    为了防止这样的情形,我们还是要限制 post 的 content 要是为空,就不得送出。
# app/models/post.rb
class Post < ApplicationRecord
  belongs_to :user
  belongs_to :group

  validates :content, presence: true
    
end
    1. git 存档

6-4 文章应该按照发表时间倒序排列

    1. 修改 groups_controller
app/controllers/groups_controller.rb
  def show
    @group = Group.find(params[:id])
    @posts = @group.posts.order("created_at DESC")
  end
    1. 使用 scope 替代直接 order
      这里的 order("created_at DESC") 是“程序语句”,但不是“功能叙述”。我们作为旁观者,只能猜测这是要按照“最近的时序排列”。

如果能改成 @group.posts.recent 可能在维护性上更直观。

这里我们还可以用 Rails 里面的一个内建 API scope 让代码更直观一些。

修改app/models/post.rb,加入一行 scope :recent, -> { order("created_at DESC")}

# app/models/post.rb
class Post < ApplicationRecord
    # ... 略
  scope :recent, -> { order("created_at DESC")}
end

然后修改 app/controllers/groups_controller.rb 中的 show

# app/controllers/groups_controller.rb
  def show
    @group = Group.find(params[:id])
    @posts = @group.posts.recent
  end
    1. git 储存

6-5 加入文章分页功能

  • 1: 安装 will_paginate
    gem 'will_paginate'
    bundle install
    rails s

  • 2: 修改 groups_controller

# app/controllers/groups_controller.rb
  def show
    @group = Group.find(params[:id])
    @posts = @group.posts.recent.paginate(:page => params[:page], :per_page => 5)
  end
  • 3: 修改 groups/show.html.erb
</tbody>
</table>

+    <div class="text-center">
+      <%= will_paginate @posts %>
+    </div>
  • 4: git 储存




7-1 本章目标

一个使用者可以选择“加入”、“退出”讨论群
群的创始者,创群一开始就应该加在群组里

7-2 建立“群成员”数据表

git checkout -b ch06

  • 1: 建立 GroupRelationship
    输入rails g model group_relationship group_id:integer user_id:integer
    执行rake db:migrate

  • 2: 设定 Group 与 User 之间的关系 ( 使用者参与的所有群)
    首先,修改 app/models/user.rb 加入以下两行

# app/models/user.rb
class User < ApplicationRecord

# .. 略

+  has_many :group_relationships
+  has_many :participated_groups, :through => :group_relationships, :source => :group
end

然后修改 app/models/group_relationship.rb,加入这两行

# app/models/group_relationship.rb
class GroupRelationship < ApplicationRecord
+  belongs_to :group
+  belongs_to :user
end

这样当捞 user.participated_groups 时,就会捞出“参与的所有群”。

  • 3: 设定 Group 与 User 之间的关系 ( 群组内的所有会员 )
# app/models/group.rb
class Group < ApplicationRecord

    # ... 略

  
+  has_many :group_relationships
+  has_many :members, through: :group_relationships, source: :user
end
  • 4: 动手测看看
    打开 rails console
    依次输入
 u = User.first
 g = Group.first
 g.members << u
 g.members
 u.participated_groups        #  看看会出现什么结果,最后执行exit退出
  • 5: git 储存

7-3 在群组里面判断“是否群组成员”实作

    1. 在 user model 内实作判断式“是否为群组的一分子”
# app/models/user.rb
class User < ApplicationRecord
  # 略 ...

  
+    def is_member_of?(group)
+      participated_groups.include?(group)
+    end
  end

然后“重开” rails console
依次输入

u = User.first
g = Group.first
u.is_member_of?(g)

观察结果

    1. 修改 groups/show.html.erb
app/views/groups/show.html.erb
<span class="pull-right">
  <% if current_user && current_user.is_member_of?(@group) %>
    <label class="label label-success"> 群组成员 </label>
  <% else %>
    <label class="label label-warning"> 不是群组成员 </label>
  <% end %>
</span>
    1. git 存档

7-4 “加入群组”或“退出群组”

实作 model 层 “加入群组”
实作 model 层“退出群组”

# app/models/user.rb
  def join!(group)
    participated_groups << group
  end

  def quit!(group)
    participated_groups.delete(group)
  end

打开 rails console

终端依次输入

u = User.first
g = Group.first
u.join!(g)
u.is_member_of?(g)
u.quit!(g)
u.is_member_of?(g)
exit     # 观察结果, 记得 git 

7-5 实际操作“加入群组”或“退出群组”

app/controllers/groups_controller.rb
+  def join
+   @group = Group.find(params[:id])
+  
+    if !current_user.is_member_of?(@group)
+      current_user.join!(@group)
+      flash[:notice] = "加入本讨论版成功!"
+    else
+      flash[:warning] = "你已经是本讨论版成员了!"
+    end
+  
+    redirect_to group_path(@group)
+  end
+  
+  def quit
+    @group = Group.find(params[:id])
+  
+    if current_user.is_member_of?(@group)
+      current_user.quit!(@group)
+      flash[:alert] = "已退出本讨论版!"
+    else
+      flash[:warning] = "你不是本讨论版成员,怎么退出 XD"
+    end
+  
+    redirect_to group_path(@group)
+  end

    private

加入与退出群组必须要是登入状态下才行,修改位於第二行的 before_action ,加入 join 和 quit 也需要验证

app/controllers/groups_controller.rb
class GroupsController < ApplicationController
-  before_action :authenticate_user! , only: [:new, :create, :edit, :update, :destroy]
+  before_action :authenticate_user! , only: [:new, :create, :edit, :update, :destroy, :join, :quit]
...
# config/routes.rb
resources :groups do
+    member do
+      post :join
+      post :quit
+    end

    resources :posts
  end
# app/views/groups/show.html.erb
<span class="pull-right">
  <% if current_user && current_user.is_member_of?(@group) %>
    <label class="label label-success"> 群组成员 </label>
+        <%= link_to("Quit Group", quit_group_path(@group), method: :post, class: "btn btn-default") %>
  <% else %>
    <label class="label label-warning"> 不是群组成员 </label>
+        <%= link_to("Join Group", join_group_path(@group), method: :post, class: "btn btn-default") %>
  <% end %>
</span>

最后 git 保存

7-6 User 在建立 group 后自动成为 group 的一员

app/controllers/groups_controller.rb
  def create
    @group = Group.new(group_params)
    @group.user = current_user
    if @group.save
+     current_user.join!(@group)
      redirect_to groups_path
    else
      render :new
    end

  end

还得记得 git 保存




8-使用者可以在“自己的后台”看过曾经发表的文章、以及创立的社团

新增一个下拉选单
可以看到自己过去曾经发表的文章
可以看到自己过去曾经参与的社团

8-2 可以看到自己参与的所有群组

git checkout -b ch07

  • 1: 产生 account 的 namespace 下的 groups_controller
    rails g controller account/groups

    1. 修改 routing
config/routes.rb
  namespace :account do
    resources :groups
  end
  • 3: 修改下拉选项
# app/views/common/_navbar.html.erb
   <ul class="dropdown-menu">
+    <li> <%= link_to("My Groups", account_groups_path) %></li>
+    <li class="divider"> </li>
     <li> <%= link_to("退出", destroy_user_session_path, method: :delete) %> </li>
   </ul>
    1. 建立 account/groups_controller.rb 下的 index action
app/controllers/account/groups_controller.rb
class Account::GroupsController < ApplicationController
  before_action :authenticate_user!

  def index
    @groups = current_user.participated_groups
  end
end
    1. 新增 “参与群组一览表”
app/views/account/groups/index.html.erb
<div class="col-md-12">

  <h2 class="text-center"> 我加入的讨论版 </h2>

  <table class="table">
    <thead>
      <tr>
        <th> # </th>
        <th> Title </th>
        <th> Description </th>
        <th> Post Count </th>
        <th> Last Update </th>
      </tr>
    </thead>

    <tbody>
      <% @groups.each do |group| %>
        <tr>
          <td> # </td>
          <td> <%= link_to(group.title, group_path(group)) %> </td>
          <td> <%= group.description %> </td>
          <td> <%= group.posts.count %> </td>
          <td> <%= group.updated_at %> </td>
        </tr>
      <% end %>
    </tbody>
  </table>
</div>
  • 6: git 储存

8-3 可以看到自己发表的所有文章

使用者在下拉选单内,可以看到 "My Posts"
使用者点选 "My Posts" 可以看到自己发表的所有文章

  • 1: 产生 account 的 namespace 下的 posts_controller
    rails g controller account/posts

    1. 建立 account/posts_controller.rb 下的 index action
# app/controllers/account/posts_controller.rb
class Account::PostsController < ApplicationController
  before_action :authenticate_user!
  def index
    @posts = current_user.posts
  end
end
    1. 修改 routing
config/routes.rb
  namespace :account do
     resources :groups
+    resources :posts
  end
  • 4: 修改下拉选项
# app/views/common/_navbar.html.erb
                <ul class="dropdown-menu">
                     <li> <%= link_to("My Groups", account_groups_path) %></li>
+                    <li> <%= link_to("My Posts", account_posts_path) %></li> 
                     <li class="divider"> </li>
                     <li> <%= link_to("退出", destroy_user_session_path, method: :delete) %> </li>
                </ul>
    1. 新增 “发表文章一览表”
# app/views/account/posts/index.html.erb
<div class="col-md-12">

  <h2 class="text-center"> 我发表过的文章 </h2>

  <table class="table">
    <thead>
      <tr>
        <th> Content </th>
        <th> Group Name </th>
        <th> Last Update </th>
        <th colspan="2"></th>
      </tr>
    </thead>

    <tbody>
      <% @posts.each do |post| %>
        <tr>
          <td> <%= post.content %> </td>
          <td> <%= post.group.title %> </td>
          <td> <%= post.updated_at %> </td>
          <td> <%= link_to('Edit', edit_group_post_path(post.group, post), class: "btn btn-default btn-xs") %></td>
          <td> <%= link_to('Delete', group_post_path(post.group, post), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-default btn-xs") %></td>
        </tr>
      <% end %>
    </tbody>
  </table>
</div>
  • 6: git 储存

9-修饰细节,使用 Helper 与 Partial

暂略

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容