如何修复 'updating a comment sent me to the wrong route'

How to fix 'updating a comment sent me to the wrong route'

我正在构建一个应用程序并且我有一个设备用户控制器,用于使用 Comment 脚手架和 Post 登录。我的问题是,当我更新评论并点击更新按钮时,当我在控制器中告诉它将我发送到 http://localhost:3000/publicaciones/1.

时,它会将我发送到路由 http://localhost:3000/publicaciones/1/comentarios

创建和删除思想将我带到正确的路线

mensajes 控制器

before_action :set_comentario, only: [:show, :edit, :update, :destroy]
  before_action :set_publicacione, only: [:new, :create, :destroy, :show]

  # GET /comentarios
  # GET /comentarios.json
  def index
    @comentarios = Comentario.all
  end

  # GET /comentarios/1
  # GET /comentarios/1.json
  def show
  end

  # GET /comentarios/new
  def new
    @comentario = Comentario.new
  end

  # GET /comentarios/1/edit
  def edit
  end

  # POST /comentarios
  # POST /comentarios.json
  def create
    @comentario = Comentario.new(comentario_params)
    @comentario.publicacione_id = @publicacione.id
    @comentario.user_id = current_user.id
    respond_to do |format|
      if @comentario.save
        format.html { redirect_to publicacione_path(@publicacione), notice: 'Comentario was successfully created.' }
        format.json { render :show, status: :created, location: @comentario }
      else
        format.html { render :new }
        format.json { render json: @comentario.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /comentarios/1
  # PATCH/PUT /comentarios/1.json
  def update
    respond_to do |format|
      if @comentario.update(comentario_params)
        format.html { redirect_to publicacione_path(@comentario.publicacione_id), notice: 'Comentario was successfully updated.' }
        format.json { render :show, status: :ok, location: publicacione_path(@comentario.publicacione_id) }
      else
        format.html { render :edit }
        format.json { render json: @comentario.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /comentarios/1
  # DELETE /comentarios/1.json
  def destroy
    @comentario.destroy
    respond_to do |format|
      format.html { redirect_to publicacione_path(@comentario.publicacione_id), notice: 'Comentario was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_comentario
      @comentario = Comentario.find(params[:id])
    end

    def set_publicacione
      @publicacione = Publicacione.find(params[:publicacione_id])
    end
    # Never trust parameters from the scary internet, only allow the white list through.
    def comentario_params
      params.require(:comentario).permit(:contenido, :puntaje_reputacion, :user_id, :publicacione_id)
    end
end

公共控制器

class PublicacionesController < ApplicationController
  before_action :set_publicacione, only: [:show, :edit, :update, :destroy]
  # GET /publicaciones
  # GET /publicaciones.json
  def index
    @publicaciones = Publicacione.all
  end

  # GET /publicaciones/1
  # GET /publicaciones/1.json
  def show
  end

  # GET /publicaciones/new
  def new
    @publicacione = Publicacione.new
  end

  # GET /publicaciones/1/edit
  def edit
  end

  # POST /publicaciones
  # POST /publicaciones.json
  def create
    @publicacione = Publicacione.new(publicacione_params)

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

  # PATCH/PUT /publicaciones/1
  # PATCH/PUT /publicaciones/1.json
  def update
    respond_to do |format|
      if @publicacione.update(publicacione_params)
        format.html { redirect_to @publicacione, notice: 'Publicacione was successfully updated.' }
        format.json { render :show, status: :ok, location: @publicacione }
      else
        format.html { render :edit }
        format.json { render json: @publicacione.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /publicaciones/1
  # DELETE /publicaciones/1.json
  def destroy
    @publicacione.destroy
    respond_to do |format|
      format.html { redirect_to publicaciones_url, notice: 'Publicacione was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_publicacione
      @publicacione = Publicacione.find(params[:id])
    end

    def set_comentarios
      @comentarios = Comentario.all
    end
    # Never trust parameters from the scary internet, only allow the white list through.
    def publicacione_params
      params.require(:publicacione).permit(:titulo, :contenido, :descripcion, :puntaje_reputacion, :user_id, :curso_id)
    end
end

confit/routes

Rails.application.routes.draw do
  resources :publicaciones do
    resources :comentarios
  end
  resources :cursos
  resources :eventos
  resources :sala_de_estudios
  devise_for :users
  resources :campus
  resources :users, only: [:show, :edit, :update]
  root 'campus#index'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

编辑视图

<h1>Editing Comentario</h1>

<%= render 'form', comentario: @comentario %>

<%= link_to 'Show', publicacione_comentario_path%> |
<%= link_to 'Back', publicacione_path(@comentario.publicacione_id) %>

窗体视图

<%= form_with(model: @comentario, url: publicacione_comentarios_path, local: true) do |form| %>
  <% if comentario.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(comentario.errors.count, "error") %> prohibited this comentario from being saved:</h2>

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

  <div class="field">
    <%= form.label :contenido %>
    <%= form.text_field :contenido %>
  </div>

  <div class="field">
    <%= form.label :puntaje_reputacion %>
    <%= form.text_field :puntaje_reputacion %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

当我点击它时,将我发送到 http://localhost:3000/publicaciones/1/comentarioshttp://localhost:3000/publicaciones/1 是预期的

您有嵌套路线

resources :publicaciones do
  resources :comentarios
end

你可以放弃他们。

resources :publicaciones
resources :comentarios

你也可以使用shallow

resources :publicaciones do
  resources :comentarios, shallow: true
end

由于你有嵌套资源,你需要在表单上设置Publicacione对象:

<%= form_with(model: @comentario, url: publicacione_comentarios_path(@publicacione), local: true) do |form| %>

然后在controller中,需要根据@publicacione设置@commentarioredirect_to publicacione_path(@publicacione)

  def update
    respond_to do |format|
      if @comentario.update(comentario_params)
        format.html { redirect_to publicacione_path(@publicacione), notice: 'Comentario was successfully updated.' }
        format.json { render :show, status: :ok, location: publicacione_path(@comentario.publicacione_id) }
      else
        format.html { render :edit }
        format.json { render json: @comentario.errors, status: :unprocessable_entity }
      end
    end
  end

  private

    def set_comentario
      @comentario = @publicacione.comentarios.find(params[:id])
    end

这个

<%= form_with(model: @comentario, url: publicacione_comentarios_path, local: true) do |form| %>

对于 new/create 是正确的,但是对于 edit/update 它应该是...

<%= form_with(model: @comentario, url: publicacione_comentario_path(@publicacione, @comentario), local: true) do |form| %>

如果你不希望两种情况有不同的形式(我不怪你)使用格式...

form_with(model: @comentario, url: [@publicacione, @comentario], local: true)

...然后 form_with 辅助方法将生成正确的路径。