I have model based form:
<h2>Add New Credit Card</h2>
<%= form_for #credit_card do |f| %>
some fields
<% end %>
routes:
resources :credit_card
credit_card_index GET /credit_card(.:format) credit_card#index
POST /credit_card(.:format) credit_card#create
new_credit_card GET /credit_card/new(.:format) credit_card#new
edit_credit_card GET /credit_card/:id/edit(.:format) credit_card#edit
credit_card GET /credit_card/:id(.:format) credit_card#show
PATCH /credit_card/:id(.:format) credit_card#update
PUT /credit_card/:id(.:format) credit_card#update
DELETE /credit_card/:id(.:format) credit_card#destroy
controller:
def new
#credit_card = CreditCard.new
end
When I try to render by form it says:
undefined method `credit_cards_path' for #<#<Class:0x00000004c37680>:0x00000004c34570>
Did you mean? credit_card_path
credit_card_index_path
credit_card_url
Its a model based form, for now I have nothing in model. I just want to render and submit will go to create method
You're using the Singular Resources:
resources :credit_card
Where you have to use Plural Resources:
resources :credit_cards
In your routes, use plural for resources definition.
resources :credit_cards
That will generate your routes like
credit_cards GET /credit_cards/:id(.:format) credit_card#show
Use resources :credit_cards instead of resources :credit_card
I'm relatively new to rails and I've been struggling with this for a couple of days. I'd be much appreciated if you can see where I've gone wrong.
When I view the page in the web browser I get the following message:
Showing C:/Users/Matt/Documents/GitHub/Outputer/app/views/studies/index.html.erb where line #8 raised:
undefined method `studies_path' for #<#:0x6b03808>
8: <%= form_for #new_study do |f| %>
studies_controller:
def index
#line = current_user.lines.find_by_id(params[:line_id])
#machine = #line.machines.find_by_id(params[:machine_id])
#studies = #machine.studies.paginate(page: params[:page], :per_page => 10)
#new_study = #machine.studies.build
end
def create
#study = current_user.lines.machines.study.build(params[:study])
if #study.save
flash[:success] = "Study created"
else
flash[:error] = "Error : Invalid study description"
end
redirect_to :back
end
index.html
....
<section>
<%= form_for #new_study do |f| %>
<div class="field">
<%= f.text_field :description, placeholder: "New study description..." %>
</div>
<%= f.submit "Create", class: "btn" %>
<% end %>
</section>
....
Study Model
....
class Study < ActiveRecord::Base
belongs_to :machine
belongs_to :line
attr_accessible :avg_speed, :avg_uptime, :avg_yield, :description, :duration, :is_active, :start_time, :stop_time, :line_id
validates ....
has_many :events, dependent: :destroy
....
end
....
rake routes:
....
save_line_machine_study PUT /lines/:line_id/machines/:machine_id/studies/:id/save(.:format) studies#save {:has_many=>:machines}
line_machine_studies GET /lines/:line_id/machines/:machine_id/studies(.:format) studies#index {:has_many=>:machines}
POST /lines/:line_id/machines/:machine_id/studies(.:format) studies#create {:has_many=>:machines}
new_line_machine_study GET /lines/:line_id/machines/:machine_id/studies/new(.:format) studies#new {:has_many=>:machines}
edit_line_machine_study GET /lines/:line_id/machines/:machine_id/studies/:id/edit(.:format) studies#edit {:has_many=>:machines}
line_machine_study GET /lines/:line_id/machines/:machine_id/studies/:id(.:format) studies#show {:has_many=>:machines}
PUT /lines/:line_id/machines/:machine_id/studies/:id(.:format) studies#update {:has_many=>:machines}
DELETE /lines/:line_id/machines/:machine_id/studies/:id(.:format) studies#destroy {:has_many=>:machines}
....
routes.rb
resources :users
resources :lines, :has_many => :machines, only: [:index, :edit, :destroy, :show, :create] do
resources :machines, only: [:new, :create, :edit, :update] do
resources :studies
end
end
If I remove the form the page works fine which would suggest its in the form. I've tested the controller commands in the console and they all appear fine - I can create a new study object.
Thanks in anticipation
When you use form_for with a model instance, it defaults to the POST action for that controller which would be your studies_path. This is usually mapped to create in the controller.
From the looks of it, you need to add a route in routes.rb to handle that post request (see resources). You will also need a create method in your studies controller.
Here is a good guide for learning the basics of routing in rails.
Although a missing route is the most common reason for that (not-very-helpful) error, it can also be raised if one or both sides of a has_many/belongs_to relationship is missing or is incorrectly defined. Another place to look is a form field for an attribute that doesn't exist in the related model.
<%= form_for #new_study %> is equivalent to <%= form_for #new_study, url: studies_url %>. As your routes are defined differently, you need to pass the url you'd like to submit the form to to the url parameter (find form_for in the Rails API docs to see what other options it takes).
Three level deep nesting is kind of ugly to maintain, so I'd suggest the following:
resources :users
resources :lines do
resources :machines
end
resources :machines do
resources :studies
end
These shallow routes are much nicer to maintain. There's also a shallow: true option on nested resources calls, see the docs.
In your case:
# With the current setup
<%= form_for #new_study, url: line_machine_studies_path(#line, #machine)
# Same, my preference
<%= form_for [#line, #machine, #new_study] %>
# If you make your routes shallow,
# #line is not nescessary, as #machine holds all information about associations
<%= form_for #new_study, url: machine_studies_path(#machine) %>
# Same, my preference, what I would do
<%= form_for [#machine, #new_study] %>
General suggestions:
#study is preferred over #new_study. #study.new_record? will tell you whether the object is a new record if you need.
There's no has_many :... option on resources routes as far as I'm aware
Google rails shallow routes for more info. Keep nesting to two levels. Think about only what information you really require when creating objects and keep the URLs and url helpers as slim as possible.
I have the following three models:
Article
Article::Line (lines of the article)
Article::Review (reviews of a line)
I want to have a route that is
/articles/11/line/2/review/new
/articles/11/line/2/review/edit
My route.rb
resources :articles do
scope module: 'article' do
resources :lines do
resources :reviews
end
end
end
I am trying to make the form_for work with both new and edit automatically:
<%= form_for [ #line.article, #line, #review ] do |f| %>
However this will produce undefined method `article_article_line_article_reviews_path' error.
What have I done wrong, or is this possible?
I have a set of nested resources -- :users and :messages.
resources :users, :only => [:show,:index] do
resources :messages
end
And also a formtastic form in the "new.html.haml" template for the Message model and it needs to use these resources:
=semantic_form_for [#user,#message] do |f|
=f.input :title
The problem is in the actual action path that is generated from [#user,#message], and it looks like this:
/users/4cdc7f9dfae434029a0000aa/messages
This is wrong because I am using a named route, so this should look like "/users/nickname/messages"
How can I make sure that #user produces a proper path output?
Edit: Here is the name routes I am using to slugify the user.
match "/users/:nickname/messages" => "messages#index"
match "/users/:nickname/messages/new" => "messages#new", :as=>:new_message
match "/users/:nickname/messages" => "messages#create", :as=>:create_message
I guess what you want is to use the nickname as the url slug. What you need for that is just the regular nested resources;
# in routes.rb
resources :users do
resources :messages
end
which would give you the same routes except they would have :id instead of :nickname in there.
Now for the actual trick that lets you use the user's nickname as the url identifier:
# user.rb
class User < ActiveRecord::Base
def to_param
self.nickname
end
end
You would automatically get the nickname in the url, and have it passed on to your controllers as params[:id] so you have to act accordingly in your controller
# users_controller.rb
…
def show
#user = User.find_by_nickname(params[:id])
end
…
This should do the trick
=semantic_form_for :message, :url => create_message_path(:nickname => #user.nickname) do |f|
# ...
I have a form partial current setup like this to make new blog posts
<% form_for([#current_user, #post]) do |f| %>
This works great when editing a post, but when creating a new post I get the following error:
undefined method `user_posts_path' for #<ActionView::Base:0x6158104>
My routes are setup as follows:
map.resources :user do |user|
user.resources :post
end
Is there a better way to setup my partial to handle both new posts and editing current posts?
map.resources :user do |user|
user.resources :posts
end
pluralize your model names in routes declaration. as you can see it says resourc-es, so you must use user-s and post-s too.
Controllers should be named UsersController and PostsController
Models should be named User and Post.
if above example still does not work for you, try a this one
map.resources :users do |u|
u.resources :posts
end