Michael Lombardo Michael Lombardo - 6 months ago 13
HTML Question

undefined method `user_revisers_path' "NoMethodError in Revisers#new "

I got this weird error I'm assuming this comes from the routes.rb part of my app. Im trying to give the chance for a user to become a reviser when they enter a form. a user can only become a reviser once so its a

has_one reviser
on
user.rb
model Thanks!

routes.rb:

Rails.application.routes.draw do
root 'pages#home'

devise_for :users ,
:path => '' ,
:path_names => { :sign_in => 'login', :sign_out => 'logout', :edit => 'profile' },
:controllers => { :omniauth_callbacks => 'omniauth_callbacks',
:registrations => 'registrations'
}

resources :users, only: [:index, :show] do
resource :reviser
end


revisers_controller:

class RevisersController < ApplicationController
before_action :set_reviser, only: [:show, :edit, :update]
before_action :authenticate_user!, except: [:show]

def index
@reviser = current_user.reviser
end

def show
end

def new
@reviser = current_user.build_reviser(params[:reviser])
@user = User.find(params[:user_id])
end

def create
@reviser = current_user.reviser.build(reviser_params)

if @reviser.save
redirect_to @reviser,notice: "saved...."
else
render :new
end
end

def edit
set_reviser
end

def update
set_reviser

if @reviser.update(reviser_params)
redirect_to @reviser, notice: "updated.."
else
render :edit
end
end

private
def set_reviser
@reviser = Reviser.find(params[:id])
end

def reviser_params
params.require(:reviser).permit(:description, :average_start, :average_end, :max_pages, :price_per, :active)
end
end


new.html

<%= form_for [current_user, @reviser] do |f| %>
<div class="row">
<div class="div.col-md-4 select">
<div class="form-group">
<label>dsd</label>
<%= f.input :description, label: false, class: 'controls',:input_html => { :id => 'description' } %>
</div>
</div>
</div>

<%= f.submit "Become Adviser", class: "btn btn-large btn-primary" %>
<% end %>


Error log:

Rendered revisers/_form.html.erb (14.7ms)
Rendered revisers/new.html.erb within layouts/application (15.9ms)
Completed 500 Internal Server Error in 48ms (ActiveRecord: 1.1ms)

ActionView::Template::Error (undefined method `user_revisers_path' for #<#<Class:0x007faf35f0cc60>:0x007faf35ee7e60>):
5: <div class="panel-body">
6: <div class="container">
7:
8: <%= form_for [current_user, @reviser] do |f| %>
9:
10: <div class="row">
11: <div class="div.col-md-4 select">
app/views/revisers/_form.html.erb:8:in `_app_views_revisers__form_html_erb___2471522092853631188_70195335070980'
app/views/revisers/new.html.erb:1:in `_app_views_revisers_new_html_erb___1451348464463745171_70195280947160'

Answer

You have a singular resource definition for your :reviser route. This makes sense for what you're trying to do, however the route generated by form_for [current_user, @reviser] will try to generate a route with both a :user_id, and an :id to identify your reviser.

So, the :id field isn't defined in your case since resource :reviser doesn't create an :id.

The solution is to explicitly set the url in your form_for to the route your want:

It should be something along the lines of:

form_for @reviser, url: edit_user_reviser_path(user_id: current_user.id)

The bigger issue with your code is that you're still directly referencing reviser by id in your controller. Under your current route settings, this will return an error on the Reviser.find() method. However, more importantly this presents a security concern since a malicious user could send an id param in the PATCH request to hijack and update a record that belongs to another user.

A simple solution is to just reference the reviser object directly on current_user.

def set_reviser
  @reviser = current_user.reviser
end