Undefined Method with "_Path" While Using Rails Form_For

form_for undefined method `user_path'

you have a students_controller which corresponds to the resources :students line in your routes.rb. This creates routes that uses the word students like students_path and new_student_path. When using form_for(@record), the url is determined from the objects class. In this case, @record is a User so the path is users_path when the object is a new record and user_path(@record) when the object is persisted. since you don't have a users_controller defined, you need to manually set the url of the form_for to fix this error

form_for @user, url: student_path(@user), html: { method: :put } do |f|

now, if you're using a partial called _form.html.erb and uses this on both the new and edit actions, you're going to have a problem since the urls for both new and edit actions are different. you have to change your views to something like this

# new.html.erb
form_for @user, url: students_path, html: { method: :post } do |f|
render 'form', f: f

# edit.html.erb
form_for @user, url: student_path(@user), html: { method: :put } do |f|
render 'form', f: f

# _form.html.erb
f.text_field :name
f.text_field :title

undefined method path with simple form

You can specify url in your form. Like this:

<%= simple_form_for @photo, url: album_photos_path do |f| %>
<%= f.error_notification %>

<div class="form-inputs">
<%= f.input :title %>
<%= f.input :description %>
</div>

<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>

But your code should also work. In your new action did you initialize both @album and @photo, something like:

def new
@album = Album.find params[:album_id]
@photo = @album.pictures.build
end

P.S above code is just a sample code and if both variables(@album and @photo) are initialized properly then rails will automatically generate correct url.

Undefined method with “_path” while using simple_form_for

Controller name should be plural so in your case it should be companies_controller

Follow these steps to change it

  • Rename controller to companies_controller.rb
  • Change controller class name to

    class CompaniesController < ActionController::Base
    # controller code
    end
  • Change in routes.rb

    resources :companies

Edit

Controller naming conventions

link in comments by Greg

Undefined method with _path while using rails form_for

Only routes created using the resources method are automatically named.

If you want to name your routes, use the :as option:

match '/static-events/new', :to => 'static_events#new', :as => :new_static_event
match '/static-events/', :to => 'static_events#index', :as => :static_events
match '/static-events/:id', :to => 'static_events#show', :as => :static_event

However, it's better to use the resources method. You must pass the "true" name of your model as the first parameter, then override the path if you want:

resources :static_events, :path => 'static-events'

undefined method `_path' in form, with routes defined at :resources

form_for needs to reference the path associated with @entry (i.e. entries_path), but your routes.rb file uses the singular form of the resource (:entry) rather than the required plural form (:entries), so the proper path names don't exist.

Rails models use the singular form, but the Rails database, controllers, views use the plural form and this is reflected in the routes file. One way to remember this is that a model is describing a single class that each object belongs to. Everything else, pretty much, is responsible for managing multiple instances, so while they themselves are singular (e.g. Controller), they refer to the objects they manage in the plural form (e.g. EntriesController, controller/entries directory).

See Ruby on Rails plural (controller) and singular (model) convention - explanation for more discussion of this.

Undefined method `user_path' in form_for

You have in your routes file:

devise_for :users

which adds:

        new_user_session GET    /users/sign_in(.:format)                   devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy

Now what you want to do is allow admin to edit the users. For this you have defined:

  # list of all users
get 'users', to: 'users#index', as: :all_users

# single user
get 'users/:id', to: 'users#show', as: :single_user

# edit user
get 'users/:id/edit', to: 'users#edit', as: :edit_user

which generates:

       all_users GET    /users(.:format)                           users#index
single_user GET /users/:id(.:format) users#show
edit_user GET /users/:id/edit(.:format) users#edit

Now in the form you are writing <%= form_for(@user) do |f| %> which by default is searching for user_path. So instead of the different routes you are defining just add:

resources :users

which will generate all the necessary routes you require and map the form to the correct path. This will save a lot of overhead like using only this <%= form_for(@user) do |f| %> will take you to the create action when the user is a new object and it will take you to the update action if the user is a persisted object.

Or if you need to user your routes then you need to do:

<%= form_for(@user, url: edit_user_path, method: :get) do |f| %>

But it always a bad idea to use GET method in form submission. These links might help you:

When should I use GET or POST method? What's the difference between them?

When do you use POST and when do you use GET?

Update:

As you need to assign a single role to the user from multiple it is better to use a select box like this:

f.collection_select(:role_id, Role.all, :id, :name)

Assuming that the user table has attribute role_id and the role table has attribute name. So this will allow you to assign a role to user. What you are printing is user.role which will always print the association instead of the role name.

Hope this helps.

undefined method user_path' form_for

Change your routes to:

resources :users, only: [:new, :create], path_names: {new: 'sign_up'}

and rename your sign_up action back to new. The reason you are getting the error is rails trying to guess the correct url for given resource. Since you have passed @user, which is an instance of User class, it will try to call "#{@user.class.model_name.route_key}_path key, which results in the error you got.

To solve the issue you need either make your routes to define users_path or you need to specify the url directly using url option. users_path can be defined by either index or create action, so the above solution will work (and will not create remaining CRUD routes, yey!)

SImple form undefined method path

Because your routing is slightly non-standard you would need to pass the url explicitly to simple_form_for

<%= simple_form_for @country, url: management_country_path(@country) do |f| %>

Rails form_for route module undefined method

Well, after diving into tons of articles, and code i found the answer and as some posts pointed it has to do with Inflections.
My app has custom inflections for spanish, in which inflections look like:

Usuario -> Usuarios
Asiento -> Asientos
ItemAsiento -> ItemsAsiento

you'll notice it pluralizes the first word instead. That being said, the following piece of code from rails source extracted from rails/activemodel/lib/active_model/naming.rb shows the internals of whats happening

 def initialize(klass, namespace = nil, name = nil)
@name = name || klass.name

raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank?

@unnamespaced = @name.sub(/^#{namespace.name}::/, "") if namespace
@klass = klass
@singular = _singularize(@name)
@plural = ActiveSupport::Inflector.pluralize(@singular)
@element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(@name))
@human = ActiveSupport::Inflector.humanize(@element)
@collection = ActiveSupport::Inflector.tableize(@name)
@param_key = (namespace ? _singularize(@unnamespaced) : @singular)
@i18n_key = @name.underscore.to_sym

@route_key = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural.dup)
@singular_route_key = ActiveSupport::Inflector.singularize(@route_key)
@route_key << "_index" if @plural == @singular
end

Since my class is under Asientos namespace, the @name becomes Asientos::Asiento, @unnamespaced = "Asiento", @singular = "asientos_asiento", @plural = "asientos_asiento" and here lays the issue. @route_key gets suffixed if plural and singular are both equal.

But why are those equal? Since Spanish inflections pluralize first word, and it does not know of namespaces, the "asientos_asiento" is considered plural (true from an inflections stand point but wrong since first part is namespace not model name).

I guess here conventions played me, since convetion seems to assume last part is always the model name, thus english plural will always work just fine.
This should not happen since rails is already detecting the namespace, and it should not rely on the @name itself but strip the namespace and then singularize and pluralize without the namespace.

Monkey patch... here we go...

Thanks to everybody.

rails 4 undefined method `_index_path' when using form_for with plural class name

Avi is a nested resource of Formations your form_for should look like this form_for(@formation, @avi), which will use the correct formation_avis_path.

For more information on nested resources check out Rails Routing from the Outside In



Related Topics



Leave a reply



Submit