Stephen
Stephen

Reputation: 13

Use or need of url: and html: with form_for - Undefined method 'xxx_path for #

Development Environment: CentOS 6.5; Ruby 2.1.1; Rails 4.1.0.rc2
Novice RoR developer, experienced in other programming languages Learning from/following the www.railstutorial.org online book

I am trying to figure out if and how to use the url: and html: modifiers with the "form_for" helper function. Looking at other posts, here on stackoverflow, the closest I have found and used as a reference is Here.

My Controller has

def apply
    @applicant = Applicant.new
end

The view (apply.html.erb) has

<div class="row">
<div class="span6 offset3">
    <%= form_for (@applicant) do |f| %>
        <%= f.label :sName, "Short Name" %>
        <%= f.text_field :sName %>

and the routes.rb file has

match '/membership/apply',        to: 'membership#apply',        via: 'get'
match '/membership/submitted',    to: 'membership#submit',       via: 'post'
match '/membership/pre_approve',  to: 'membership#pre_approval', via: 'put'
match '/membership/finalize_app', to: 'membership#finalize_app', via: 'put'
match '/membership/approve',      to: 'membership#approve',      via: 'post'  
match '/membership/endorse',      to: 'membership#endorse',      via: 'put'
match '/membership/status',       to: 'membership#status',       via: 'get'


when I visit localhost:3000/membership/apply, I get the following error-

undefined method 'applicants_path' for #

and when I've tried using the url: and html: hashes -

<%= form_for (@applicant), url: membership, html: { method: :get } do |f| %>

I then receive the error-

undefined local variable or method 'membership' for #

Is this more of a routing issue with the route.rb file? Is the use of the url: and html: modifiers correct?

Upvotes: 1

Views: 169

Answers (2)

Richard Peck
Richard Peck

Reputation: 76784

Your error is because you're using membership for your url argument. membership (in this sense) will be treated as a local variable, and means you don't have it defined

You'll need to pass a route to your url arg:

<%= form_for (@applicant), url: membership_path do |f| %>

Secondly, are you sure you want to use method: :get? If you're applying for a position, I'm sure you'll need to POST the data to your server?


I'd do this:

#config/routes.rb
resources :memberships, path_names: { new: "apply" } #-> creates /memberships/apply

#app/controllers/memberships_controller.rb
Class MembershipsController < ApplicationController
    def new
        @applicant = Membership.new #-> assuming you want to use your membership model?
    end
end

#app/views/memberships/new.html.erb
<%= form_for @applicant do |f| %> #-> Rails uses the ActiveRecord object to build routes for form etc

Upvotes: 1

Buck Doyle
Buck Doyle

Reputation: 6397

The form_for method applies some Rails magic to route the submitted form. Since you’re not using RESTful routes, you need to specify the endpoint, as you guessed in the second form_for. But membership isn’t the correct route helper method. Run rake routes as Jack suggested in the comment and you’ll find the route is called membership_apply, which means your form_for should look like this:

<%= form_for (@applicant), url: membership_apply_path, html: { method: :get } do |f| %>

(The other option is membership_apply_url if you want a full URL rather than just a path.)

Apart from your immediate problem: your proliferation of custom routes signals that you may need some intermediary objects that can be treated as their own resources. Or maybe you need a state machine implementation to move a Membership along through the process.

Upvotes: 3

Related Questions