NoMethodError for a method that exists - ruby-on-rails

Well, i'm new to rails, but not new to the rails way and i've got an error that i dont know how to fix it.
I've created the controller and than the view.
Controller:
class ReclamacoesController < ApplicationController
def new
#reclamacao = Reclamacao.new
end
end
and than, the view under Views>controllerName>new.html.erb.
<%= form_for #reclamacao do |f| %>
<%= f.text_field :titulo %>
<% end %>
The model Reclamacao exist.
I've created the resource routes for it too.
resources :reclamacoes
So, when i access /reclamacoes/new an exception is thrown.
NoMethodError in Reclamacoes#new
undefined method `reclamacaos_path' for #<#<Class:0x00000001fc0660>:0x00000001fba850>
Extracted source (around line #1):
<%= form_for #reclamacao do |f| %>
<%= f.text_field :titulo %>
<% end %>
Rails.root: /home/ubuntu/workspace/aqueleprojetoprivate/medicos
Application Trace | Framework Trace | Full Trace
app/views/reclamacoes/new.html.erb:1:in `_app_views_reclamacoes_new_html_erb___3194888715597102324_16164860'
the routes:
reclamacoes GET /reclamacoes(.:format) reclamacoes#index
POST /reclamacoes(.:format) reclamacoes#create
new_reclamaco GET /reclamacoes/new(.:format) reclamacoes#new
edit_reclamaco GET /reclamacoes/:id/edit(.:format) reclamacoes#edit
reclamaco GET /reclamacoes/:id(.:format) reclamacoes#show
PATCH /reclamacoes/:id(.:format) reclamacoes#update
PUT /reclamacoes/:id(.:format) reclamacoes#update
DELETE /reclamacoes/:id(.:format) reclamacoes#destroy
What is wrong?

Rails is trying to automatically guess plurals. The problem is that your resource is reclamacao which Rails is turning into reclamacaos plural. But you have named it as reclamacoes
I suggest either changing names or instruct Rails to use better plurals. Here's a relevant article: How do I override rails naming conventions?

Take a look at the output from rake routes. You will notice a spelling error
reclamacoes GET /reclamacoes(.:format) reclamacoes#index
POST /reclamacoes(.:format) reclamacoes#create
new_reclamaco GET /reclamacoes/new(.:format) reclamacoes#new
edit_reclamaco GET /reclamacoes/:id/edit(.:format) reclamacoes#edit
reclamaco GET /reclamacoes/:id(.:format) reclamacoes#show
PATCH /reclamacoes/:id(.:format) reclamacoes#update
PUT /reclamacoes/:id(.:format) reclamacoes#update
DELETE /reclamacoes/:id(.:format) reclamacoes#destroy
Based on the above output, the correct path name is reclamacoes path.
Rails emphasizes Convention over Configuration, and you have different spellings in your models, views and controllers.

Related

Rails Undefined Method Path for New

I am relatively new to rails but having a real problem with something that I know should be really simple. I have a model called channel, in it I have a simple new method, in the view I have form but every time I try and load it, I get an error to say:
undefined method `channels_path'
My view (new.html.erb) is really simple, for the minute it just has a button in it with a name and a value, it just looks like this:
<%= simple_form_for #channel do |f| %>
<%= f.error_notification %>
<%= f.button :submit, 'Free Plan', name: 'plan', value: 'free' %>
<% end %>
My Controller has:
def new
#channel = Channel.new
end
And in my routes I have:
resources :channel
Output form a rake routes is:
channel_index GET /channel(.:format) channel#index
POST /channel(.:format) channel#create
new_channel GET /channel/new(.:format) channel#new
edit_channel GET /channel/:id/edit(.:format) channel#edit
channel GET /channel/:id(.:format) channel#show
PATCH /channel/:id(.:format) channel#update
PUT /channel/:id(.:format) channel#update
DELETE /channel/:id(.:format) channel#destroy
Which all looks how I expect. But as the error says there is no channels_path, but as far as I am aware, there shouldn't be.
I am sure this is supposed to be really simple but I just cannot see what I am doing wrong. Can anybody help?
Many thanks
David
EDIT
I have updated the route to be:
resources :channels
I can now load the form, however I now get the error when trying to submit it:
param is missing or the value is empty: channel
Being caused by:
# only allow specific params
def channel_params
params.require(:channel).permit(:name,
:slug,
:description,
:plan,
:subscription_ends
)
end
I am assuming singular is correct here based on the model, but have tried plural too with no luck. Any more thoughts?
Many thanks
Edit
Got it working in the end, it appears you have to have at least one input in your form. I added an input for the name field and it started working.
Many thanks to everyone that commented
According to your rake task, the path should be
channel_path
If it's not working with the simple_form_for helper, it's probably because you should have set up your routes as resources: channels
UPDATE
The new bug is coming from nothing being received by the controller for :channel
Try adding a field like so
f.hidden_field :plan, :value => "free"

Rails routing error with form_tag

Firstly, I am new to Rails so please excuse me if this is a lame newbie question
I am creating specials (which belongs_to :shop) with a rails form_tag
In my admin/specials/new.html.erb, the form looks like this:
<%= form_tag new_admin_shop_special_path(#current_shop) do |f| %>
<input type = "number" name = "product_ids" />
<% end %>
(The path new_admin_shop_special_path definitely does exist)
In rake routes I have:
POST /admin/shops/:shop_id/specials(.:format) admin/specials#create
new_admin_shop_special GET /admin/shops/:shop_id/specials/new(.:format) admin/specials#new
My admin/specials_controller.rb has:
def new
end
def create
special = #current_shop.specials.build
special.add_products(params[:product_ids])
redirect_to admin_shop_shipping_options_path, notice: "#{special.id}"
end
(The notice is for debugging)
So, problem is, if I submit the form, I get an error saying
Routing Error
No route matches [POST] "/admin/shops/dear-rae/specials/new"
Help.
This should work, assuming you use resources:
<%= form_tag admin_shop_specials_path(#current_shop) do |f| %>
And yes, the path with new on the end does exist, but only with GET method. When you submit your form, POST method is used, which is not applicable for this route.

Method Accesibility/Scope - NoMethodError

I'm working on my first rails project and I have a problem that I just cannot figure out.
I generated a Scaffold for an object named Archive
to this object I added the method processfile
when I try to link_to said method from Archives#Index I'm getting this:
undefined method `processfile' for #<Archive:0x702de78>
This is the model archive.rb
class Archive < ActiveRecord::Base
belongs_to :users
attr_accessible :file, :user_id
mount_uploader :file, FileUploader
end
This is the code on the index.html.erb (belonging to archives)
<% #archives.each do |archive| %>
<tr>
<td><%= archive.file%></td>
<td><%= User.find(archive.user_id).name %></td>
<td>
<%= link_to 'Download', archive.file_url %>
::
<%= link_to 'Show', archive %>
::
<%= link_to 'Edit', edit_archive_path(archive) %>
::
<%= link_to 'Delete', archive, confirm: 'Esta Seguro?', method: :delete %>
::
<%= link_to "Process", archive.processfile %>
</td>
</tr>
<% end %>
this is the routes.rb line:
match "archives/processfile/:id" => "archives#processfile", :as => :processfile
the processfile method defined whitin archives_controller.rb doesn't have anything on it, i just wanted to test the functionality since I'm having a hard time getting the grip of the "rails way"
archives_controler.rb
def processfile
# #archive = Archive.find(params[:id])
#do something with the archive
end
All in all, what I ultimately want to achieve is to call the processfile method on a given archive(taken from the index table) to do something with it. On the example, I watered down the method call (not passing an archive or archive.file to it) to make it run, to no avail.
I've searched a lot (on google and in here) and haven't found a clear guide that would address my problem, probably because i'm new and can't fully grasp the concepts behind rails MVC.
I've read something about methods only being accessed by same controlers but I've seen sample code when people call methods on controllers from index views without declaring them as helpers. o.0
I know it's probably a silly confusion, but I can't figure it out :(
The way you've structured your route (i.e., match "archives/processfile/:id" => "archives#processfile") means that it's expecting an archive id to be passed. You need to adjust your link_to to pass one:
# app/archives/index.html.erb
<%= link_to "Process", processfile_path(archive.id) %>
The error you're receiving is because you're trying to call an instance method called processfile on archive, but there's presumably no method by that name. The second parameter of the link_to helper is a path, not an instance method.
EDIT:
If you're looking to make your routes more RESTful (which you should do if you've created an Archive resource), you can generate all your CRUD routes by declaring resource :archives in your routes. Then, within a block, you can declare a block of member routes, all of which will route to the specified action in your archive_controller.rb and enable you to pass an archive id to the action.
# config/routes.rb
resources :archives do
member do
get 'processfile'
end
end
You added the processfile method to your ArchiveController. That does not make the method available to the Archive model. If you want the method to be available to instances of Archive models then you need to put it inside the model as an instance method.
If you what you want to do is place a route to the action processfile in your ArchiveController then you can do so by adding link_to "Process", processfile_path(id: archive.id)

Rails: how are paths generated?

In Rails 3, when a scaffold is generated for instance for a 'Category' the will be a categories_path (and a edit_category_path(#category), ...) used in the erb views.
This is not a variable that can be found anywhere and probably is generated. However in my case, for a different entity, Article, I first generated the model and then the controller. Now when I try output an articles_path, I get a
undefined method `articles_path' for #<#:0x000001019d1be0>
I cannot even use a <%= form_for(#article) do |f| %> as this generates the same error.
What am I supposed to do?
My routings are like this:
resources :categories do
resources :articles
end
The articles resource is within the categories scope, so the correct path to use would be category_articles_path(#category) or edit_category_articles_path(#category, #article). To do this for your form_for, try:
<%= form_for([#category, #article]) do |f| %>
As article lives in the category scope, you need to use category_articles_path.

Multiple forms on a single page

I've got an app that's in invite-only beta right now. Problem is, I can't get the invite system to work. :(
On my root page there's a login form (which works just fine), and I'm trying to add a "request invite" form on the same page. I started doing it by putting the form for InviteRequest (ActiveRecord) inside a partial, in the "views" folder for "InviteRequest". The app is definitely calling this partial, but I'm getting the following error:
NoMethodError in User_sessions#new
Showing app/views/invite_request/_new.html.erb where line #2 raised:
undefined method `invite_requests_path' for #<ActionView::Base:0x25b3248>
Extracted source (around line #2):
1: <% #invite_request = InviteRequest.new() %>
2: <% form_for #invite_request do |ir| %>
3: <%= ir.label :email %>
4: <%= ir.text_field :email %>
5: <% end %>
I also read through the "Multiple Models in a Form" section of my trusty copy of "Agile Web Development with Rails", about maybe doing this with a "fieldset" tag, but not sure if this is the right approach.
Thx.
Your form_for #invite_request is trying to figure out where the results from the form should be posted. It does this by looking at the routes and finding one that matches the resource and action needed. In your case I'm guessing you haven't set up routes for InviteRequest. You either need to set up routing for InviteRequest or specify the URL to be posted to in form_for.
form_for #invite_request, :url => { :controller => 'application', :action => 'request_invite' } do |form|
...

Resources