0

I am building an app and I have a device user controller, for login with scaffold of Comment and Post. My problem is that when I update a comment and hit the button update it send me to the route http://localhost:3000/publicaciones/1/comentarios when I have tell it in the controller to send me to http://localhost:3000/publicaciones/1.

The create and delete thought send me to the correct routes

mensajes controller

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

publicaciones controller

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

edit view

<h1>Editing Comentario</h1>

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

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

Form view

<%= 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 %>

When I click it send me to http://localhost:3000/publicaciones/1/comentarios but http://localhost:3000/publicaciones/1 was expected

Kamal Panhwar
  • 2,345
  • 3
  • 21
  • 37

3 Answers3

0

You have nested routes

resources :publicaciones do
  resources :comentarios
end

You can abandon them.

resources :publicaciones
resources :comentarios

Also you can use shallow

resources :publicaciones do
  resources :comentarios, shallow: true
end
mechnicov
  • 12,025
  • 4
  • 33
  • 56
0

Since you have nested resources, you need to set the Publicacione object on the form:

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

Then, in the controller, you need to set @commentario based on @publicacione, and redirect_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
CAmador
  • 1,881
  • 1
  • 11
  • 19
  • does not seem to go, i think mu problem is that when i hit update it does not goes to the function update, is there any way i can test this? changed all the things ypu said but the behaviors is still the same, it send me to the route if i would have redirect_to @comment, when it crearly does not said that – LUCAS RODRIGUEZ ERRAZURIZ Apr 27 '19 at 16:41
  • Yeah, the easy way is just add something like 'booom' right `def update`. Better options are `log.debug('im here')` and `byebug`. The later will stop the execution and bring up a debugger in the `rails s` command. – CAmador Apr 27 '19 at 16:51
  • called byebug and does not appear in the debugger, i really think that it doesnt go to the update function. also in the console appear this bug Started PATCH "/publicaciones/1/comentarios" for 172.19.0.1 at 2019-04-27 16:57:39 +0000 web_1 | Cannot render console from 172.19.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 maybe it is of some help, any idea what could be making it not go to the update fuction? – LUCAS RODRIGUEZ ERRAZURIZ Apr 27 '19 at 16:59
  • Start the server with `rails s -b 0.0.0.0` to accept request from every IP. – CAmador Apr 27 '19 at 17:02
  • Ok ill try, the problem is that the error is the same when running on heroku, runing the server with rails s -b 0.0.0.0 does not work :( – LUCAS RODRIGUEZ ERRAZURIZ Apr 27 '19 at 17:20
0

This

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

Is correct for new/create but for edit/update it should be...

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

If you don't want to have different forms for the two conditions (and I don't blame you) use the format...

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

...and then the form_with helper method will generate the correct path.

SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53
  • Thanks for the answer, this was what i fixed it for me. could you please explain me why this difference exist between both forms? – LUCAS RODRIGUEZ ERRAZURIZ May 01 '19 at 18:59
  • It's because the RESTful path for updating a record is different than for creating a record (you can google REST apis) and rails does a good job of figuring out what's needed when building a form based on whether the form object is #new_record? or #persisted? but when you explicitly supply a path, that overrides rails defaults. – SteveTurczyn May 02 '19 at 15:54