/YYYY/MM/Title-Slug URL 结构与Friendly_Id 解决方案在#edit 上阻塞

2023-12-13

根据我得到的指导先前的问题在解决我的实现 /YYYY/MM/Slug URL 结构的原始问题,我希望得到一些帮助来解决我在尝试编辑帖子时收到的错误:

没有路由匹配 [PATCH]“/blog/2015/09/example-post/blog/2015/09/example-post”

以下是所有有问题的文件(使用相同的非常简单的脚手架博客):

$ rails new blog
[...]
$ cd blog
# (Add friendly_id to Gemfile & install)
$ rails generate friendly_id
$ rails generate scaffold post title content slug:string:uniq
[...]
$ rake db:migrate

路线.rb

Rails.application.routes.draw do
  scope 'blog' do
    get     '',                       to: 'posts#index',  as: 'posts'
    post    '',                       to: 'posts#create'
    get     '/new',                   to: 'posts#new',    as: 'new_post'
    get     '/:year/:month/:id/edit', to: 'posts#edit',   as: 'edit_post'
    get     '/:year/:month/:id',      to: 'posts#show',   as: 'post'
    patch   '/:id',                   to: 'posts#update'
    put     '/:id',                   to: 'posts#update'
    delete  '/:year/:month/:id',      to: 'posts#destroy'
  end
end

post.rb

class Post < ActiveRecord::Base
  extend FriendlyId
  friendly_id :title, use: :slugged

  def year
    created_at.localtime.strftime("%Y")
  end

  def month
    created_at.localtime.strftime("%m")
  end
end

posts_controller.rb

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  def index
    @posts = Post.all
  end

  def show
    @post = Post.friendly.find(params[:id])
  end

  def new
    @post = Post.new
  end

  def edit
    @post = Post.friendly.find(params[:id])
  end

  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to post_path(@post.year, @post.month, @post), notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to post_path, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_post
      @post = Post.friendly.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def post_params
      params.require(:post).permit(:title, :content, :slug)
    end
  end
end

posts_helper.rb

module PostsHelper

  def post_path(post)
    "blog/#{post.year}/#{post.month}/#{post.slug}"
  end

  def edit_post_path(post)
    "#{post.year}/#{post.month}/#{post.slug}/edit"
  end

end

应用程序/视图/帖子/index.html.erb

<p id="notice"><%= notice %></p>

<h1>Listing Posts</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th>Slug</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
  <% @posts.each do |post| %>
    <tr>
      <td><%= post.title %></td>
      <td><%= post.content %></td>
      <td><%= post.slug %></td>
      <td><%= link_to 'Show', post_path(post) %></td>
      <td><%= link_to 'Edit', edit_post_path(post) %></td>
      <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Post', new_post_path %>

总而言之,以下是有效的:

  • /博客/索引
  • /博客/2015/09/示例帖子
  • 创建新帖子
  • 销毁帖子

…什么不起作用:

  • 编辑帖子(带有表单的编辑页面将呈现,但提交更改后,您将收到上述错误 - 并且更改永远不会到达数据库)

我认识到这个重复问题可能与此 edit_post_path 覆盖有关,但以下尝试强制正确的 PATCH 路由没有效果:

  1. 将 PATCH 路由更新为patch '/:year/:month/:id', to: 'posts#update'
  2. 将更新后的 PATCH 路由命名为as: 'patch'并将 PATCH 路径覆盖添加到 posts_helper:

    def patch_path(post)
      "#{post.year}/#{post.month}/#{post.slug}"
    end
    
  3. 将覆盖更改为:

    def patch_path(post)
      ""
    end
    
  4. 取消命名并将 PATCH 路由更改为patch '', to: 'posts#update'

看看 posts_controller,看起来问题不存在,因为它不是重定向不是问题 - 我不明白为什么@post.update(post_params)会有问题的:

  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

据我所知,URL 中的重复是在 PATCH 操作之前发生的,这使我们回到了编辑流程 - 它必须将重复传递到 PATCH,在那里它最终会被阻塞。有想法吗?提前致谢!

EDIT

编辑.html.erb

<h1>Editing Post</h1>

<%= render 'form' %>

<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>

_form.html.erb

<%= form_for(@post) do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
        <% @post.errors.full_messages.each do |message| %>
        <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br>
    <%= f.text_field :content %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

看来主要问题出在助手身上。返回的路径需要以斜杠开头:

module PostsHelper
  def post_path(post)
    "/blog/#{post.year}/#{post.month}/#{post.slug}"
  end

  def edit_post_path(post)
    "/blog/#{post.year}/#{post.month}/#{post.slug}/edit"
  end
end

如果没有开始斜杠,浏览器会将它们视为相对路径,将它们附加到当前路径(这就是为什么你最终会得到/blog/2015/09/example-post/blog/2015/09/example-post提交编辑表单时)。

您还需要确保您的patch and put路线一致:

get     '/:year/:month/:id',      to: 'posts#show',   as: 'post'
patch   '/:year/:month/:id',      to: 'posts#update'
put     '/:year/:month/:id',      to: 'posts#update'
delete  '/:year/:month/:id',      to: 'posts#destroy'

最后控制器需要包括PostsHelper并将其方法用于重定向 URLcreate and update:

class PostsController < ApplicationController
  include PostsHelper
...
  def create
    @post = Post.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to post_path(@post), notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to post_path(@post), notice: 'Post was successfully updated.' }
        format.json { render :show, status: :ok, location: @post }
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end
...
end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

/YYYY/MM/Title-Slug URL 结构与Friendly_Id 解决方案在#edit 上阻塞 的相关文章

随机推荐

  • 致命:需要一次修改

    我的仓库有 3 次提交 我想压缩为一 I ran git rebase i HEAD 3并得到这个错误 fatal Needed a single revision invalid upstream HEAD 3 我能够跑git rebas
  • 创建一个包含 R 中多个矩阵的平均值的矩阵[重复]

    这个问题在这里已经有答案了 我有多个具有相同尺寸的矩阵 如下所示 gt A x y z 1 2 4 3 2 1 5 7 gt B x y z 1 4 3 3 2 1 8 7 gt C x y z 1 4 3 3 2 1 8 7 gt 如何创
  • VBA listobject不会添加行

    我有一个带有几张表的工作表 每张表都有两个表 listobjects 我还有一个用户窗体 允许用户在表中添加 编辑 删除行 这些表是静态的 这意味着它们永远存在并且永远不会被删除 它们位于同一位置并且永远不会移动 我还以不同的方式 通过索引
  • 分层抽样 - 观察不足

    我想要实现的是从每组中获取 10 的样本 这是 2 个因素的组合 新近度和频率类别 到目前为止我已经考虑过包裹sampling和功能strata 这看起来很有希望 但我收到以下错误 并且很难理解错误消息以及错误所在或如何解决此问题 这是我的
  • 如何卸载新 WooCommerce 2.3.x 加载的 select2 脚本/样式?

    我们是主题开发人员 我们已经使用 select2 http select2 github io 我们的 WordPress 主题中 HTML 中的 SELECT 框的脚本 刚刚发布的新 WooCommerce 2 3 x 现在也使用 sel
  • MSChart / Asp.net 图表不显示工具提示

    我有一个仪表板页面 我在其中使用各种 MSCharts 我为每个图表定义了一个类 当我运行每个图表类并定义其系列属性时 我在该图表中定义系列的工具提示 如下所示 Series 0 ToolTip Date VALX d nTotal Qty
  • ICommand CanExecuteChanged 未更新

    我正在尝试 MVVM 模式基础级别 并对 ICommand CanExecute 更改感到震惊 我的 XAML 绑定如下
  • 调整图像亮度

    对于 Windows Phone 应用程序 当我通过滑块调整亮度时 它工作正常 将其移至右侧 但是当我回到之前的位置时 图像不是变暗 而是变得越来越亮 这是我基于像素操作的代码 private void slider1 ValueChang
  • SQL / MySQL - 按列长度排序

    在 MySQL 中 有没有办法按列的长度 字符 对结果进行排序 例如 myColumn lor lorem lorem ip lorem ips lorem ipsum 我想首先按最小的列长度 lor 对结果进行排序 然后以最大的列长度 l
  • 为什么析构函数挂起

    下面的代码工作正常 但是 当我启用p b in GetValue 代码失败 调试断言失败 为什么 class A int p public A p nullptr A if p nullptr delete p void GetValue
  • 如何为 json 负载定义 swagger 注释

    如何为此示例定义 swagger 注释 API TenantConfiguration 作为 json 负载获取 Consumes application json application xml POST public Message c
  • 本地主机上跨子域的用户身份验证

    我正在我的本地主机上构建一个应用程序 当我通过一个子域 例如 sub localhost 登录时 我需要在应用程序的所有其他子域 例如 sub2 localhost sub3 localhost 中使用 Auth 访问该登录用户 我将其更改
  • Pandas 风格:在整行上绘制边框,包括多索引

    我在 jupyter 笔记本中使用 pandas 样式来强调此数据框中子组之间的边界 从技术上讲 在每个更改的多重索引处绘制边框 但忽略最低级别 some sample df with multiindex res np repeat re
  • wordnet getDict() 找不到 Wordnet 词典

    当使用以下代码使用 WordNet 中的 Lemmatizer 算法时 gt initDict C Program Files x86 WordNet 2 1 dict 1 TRUE if initDict C Program Files
  • 在 Python 中将多字节字符转换为 7 位 ASCII

    我正在通过 Python 脚本下载并解析网页 我需要它 被编码为 7 位 ASCII 以便进一步处理 我正在使用 请求库 http docs python requests org en master 在一个 virtualenv 基于 U
  • 如何在 ListView 中访问 WebView 的 NavigateToString 属性

    我有一个ListView除其他外 其中包含WebView 当一个ListViewItem在此列表中被选中 我想将 HTML 绑定到WebView通过NavigateToString方法 WebView 需要位于绑定列表中 因为它绑定到项目列
  • 将本地 PDF 文件加载到 WebView 中

    我正在尝试将以下功能放入我正在编写的 iOS 应用程序中 在 XCode 中的项目的资源文件夹中发送一组 PDF 将 PDF 复制到应用程序目录 在网络视图中打开 PDF 据我所知 前两个步骤工作正常 我在复制操作后使用 FileManag
  • 使用 WPF WriteableBitmap.BackBuffer 绘制线条

    您是否知道任何库提供使用 WPF WriteableBitmap 和理想情况下 BackBuffer 绘制简单形状 线条和可选的其他形状 的方法 我知道有一个针对 silverlight 的 WriteableBitmapEx 项目 但是有
  • 如何使用 VBA 代码添加新电子表格

    我正在创建一个宏 宏的部分功能是让 VBA 创建一个新的电子表格 由于发行的性质 名称将会改变 我需要向此电子表格添加代码 无论如何我可以做到这一点吗 乔克已经解释了它是如何工作的 我会更进一步 添加工作表的语法是 expression A
  • /YYYY/MM/Title-Slug URL 结构与Friendly_Id 解决方案在#edit 上阻塞

    根据我得到的指导先前的问题在解决我的实现 YYYY MM Slug URL 结构的原始问题 我希望得到一些帮助来解决我在尝试编辑帖子时收到的错误 没有路由匹配 PATCH blog 2015 09 example post blog 201