【问题标题】:No route matches [PATCH] "/users/1/articles" error on Ruby on RailsRuby on Rails 上没有路由匹配 [PATCH]“/users/1/articles”错误
【发布时间】:2019-01-27 10:28:46
【问题描述】:

我对此非常陌生,我正在尝试实现一个待办事项列表,它允许使用带有用户身份验证的标签。更新任务时,我收到一个路由错误,指出没有路由匹配 [PATCH]“/users/1/articles”。我怀疑是因为我在更新文章时没有传递文章ID。谁能帮助指导我如何解决这个问题?任何建议将不胜感激,谢谢!

来自错误页面的路由

user_article_path   GET /users/:user_id/articles/:id(.:format)  
articles#show

PATCH   /users/:user_id/articles/:id(.:format)  
articles#update

PUT /users/:user_id/articles/:id(.:format)  
articles#update

DELETE  /users/:user_id/articles/:id(.:format)  
articles#destroy

Routes.rb

Rails.application.routes.draw do
  get 'sessions/new'
  get 'welcome/index'
  get  '/signup',  to: 'users#new'
  post '/signup',  to: 'users#create'
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'

  resources :users do
      resources :articles 
  end
  get 'tags/:tag', to: 'articles#index', as: :tag, :constraints  => { :tag => /[^\/]+/ }

  root 'welcome#index'
end

article.rb


class Article < ApplicationRecord
attr_accessor :content, :name, :tag_list
   before_create :downcase_fields
has_many :taggings , dependent: :destroy
has_many :tags, through: :taggings, dependent: :destroy 
 belongs_to :user    
 validates :user_id, presence: true
 validates :title, presence: true,
                   length: { minimum: 1}
  def self.tagged_with(name)
   Tag.find_by_name!(name).articles
  end


   def downcase_fields
      self.title.downcase
   end

def self.tag_counts
  Tag.select("tags.*, count(taggings.tag_id) as count").
    joins(:taggings).group("taggings.tag_id")
end

def tag_list
  tags.map(&:name).join(", ")
end

def tag_list=(names)
  self.tags = names.split(",").map do |n|
    Tag.where(name: n.strip).first_or_create!
  end
end

def self.search(term)
  if term
    where('title LIKE ?', "%#{term}%").order('id DESC')
  else
    order('id DESC') 
  end
end
end

articles_controller

class ArticlesController < ApplicationController
  before_action :correct_user

  def index
      @user = User.find(params[:user_id])
      @articles = @user.articles.search(params[:term])
#    if params[:tag]
 #     @articles =  @user.articles.tagged_with(params[:tag])
 #   else
 #     @articles =  @user.articles.all
 #   end
  end

    def show
        @user = User.find(params[:user_id])
    @article = @user.articles.find(params[:id])
  end
 def new
      @user = User.find(params[:user_id])
  @article = @user.articles.new
end

def edit
      @user = User.find(params[:user_id])
  @article = @user.articles.find(params[:id])
end

def create
  @user = User.find(params[:user_id])
  @article = @user.articles.new(article_params)

  if @article.save
    redirect_to user_articles_url
  else
    render 'new'
  end
end

def update
   @user = User.find(params[:user_id])
  @article = @user.articles.find(params[:id])

  if @article.update(article_params)
    redirect_to user_articles_path
  else
    render 'edit'
  end
end

def destroy
  @user = User.find(params[:user_id])
  @article = @user.articles.find(params[:id])
  @article.destroy

  redirect_to user_articles_path
end
private
  def article_params
    params.require(:article).permit(:title, :text, :tag_list, :term)
  end


    # Confirms a logged_in user_
    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end

    # Confirms the correct user
    def correct_user
      @user = User.find(params[:user_id])
      redirect_to(root_url) unless current_user?(@user)
    end
end

db.schema.rb

ActiveRecord::Schema.define(version: 2019_01_27_093653) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "articles", force: :cascade do |t|
    t.string "title"
    t.text "text"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "user_id"
    t.index ["user_id"], name: "index_articles_on_user_id"
  end

  create_table "taggings", force: :cascade do |t|
    t.bigint "tag_id"
    t.bigint "article_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "user_id"
    t.index ["article_id"], name: "index_taggings_on_article_id"
    t.index ["tag_id"], name: "index_taggings_on_tag_id"
    t.index ["user_id"], name: "index_taggings_on_user_id"
  end

  create_table "tags", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "name"
    t.string "email"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "password_digest"
    t.string "remember_digest"
    t.index ["email"], name: "index_users_on_email", unique: true
  end

  add_foreign_key "articles", "users"
  add_foreign_key "taggings", "articles"
  add_foreign_key "taggings", "tags"
  add_foreign_key "taggings", "users"
end

用户控制器

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update]
  before_action :correct_user,   only: [:edit, :update]

  def show
    @user = User.find(params[:id])
          redirect_to user_articles_path(@user)

  end

  def new
    @user = User.new
  end

  def index
    @users = User.paginate(page: params[:page])
  end

  def create
    @user = User.new(user_params)
    if @user.save
      log_in @user
      flash[:success] = "Welcome to the To-Do-Manager!"
      redirect_to user_articles_path(@user)
    else
      render 'new'
    end
  end

   def edit
    @user = User.find(params[:id])
  end

   def update
    @user = User.find(params[:id])
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  private

_form.html.erb(创建和更新共享同一个表单)


<%= form_with model: @article,url: user_articles_path(@user), local: true do |form| %>

  <% if @article.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@article.errors.count, "error") %> prohibited
        this article from being saved:
      </h2>
      <ul>
        <% @article.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <p>
    <%= form.label :Task %><br>
    <%= form.text_field :title %>
  </p>

  <p>
    <%= form.label :Deadline %><br>
    <%= form.text_area :text %>
  </p>

  <p>
    <%= form.label :tag_list, "Tags (separated by commas)" %><br />
    <%= form.text_field :tag_list %>
  </p>

  <p>
    <%= form.submit %>
  </p>

<% end %>

【问题讨论】:

  • 我没有使用form_withform_for 但问题似乎来自您的部分_form.html.erb。您在此部分中有一个表格。此表单应指向控制器的创建操作。但是您在表格中提到的路径是索引操作的路径:user_articles_path(@user) 这是不正确的。在您的控制台中输入rails routes 并找到控制器articles 的创建操作的路由路径。换成这条路线。 (也别忘了加method: post)。
  • 创建新条目工作正常,但修改后我无法再创建新条目了。
  • 嗯好的。你能发布你的错误的完整跟踪吗?尤其是触发错误的那一行代码..
  • 哦抱歉我有语法错误!非常感谢!听从您的建议后,它的工作原理!谢谢
  • 顺便说一句。您提到了用于创建和编辑的相同表单。对我来说这是不可能的。因为要更新,您必须输入更新操作的路径(+ 方法patch)并添加第二个值(用户的值和文章的值)。对于创建,您必须输入创建路径(+方法post)和单个值(用户ID)。

标签: ruby-on-rails routing


【解决方案1】:

根据您的路线,您的用户文章路径应该是单数:

<%= form_with model: @article, url: user_article_path(@user), local: true do |form| %>

【讨论】:

    【解决方案2】:

    您的路由需要两个参数:用户 (:user_id) 和文章 (:id),您只传递用户 user_articles_path(@user) 并且还使用复数形式,并且该路由不存在该 HTTP 方法。

    你必须使用url: user_article_path(@user,@article)(或者你可以使用快捷版本url: [@user, @article])。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      • 2016-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多