Rails Nested routes undefined method - ruby-on-rails

I keep getting an
undefined method 'orders_path' for #<#<Class:0x007faefee50a88>:0x007faefee414e8>
when navigating to my new order path url /users/1/orders/new
Been stuck on this, not sure what the deal is.
Routes:
devise_for :users, :path => 'accounts'
resources :users, only: [:index, :show] do
resources :orders
end
root index:
<%= link_to "Create an Order", new_user_order_path(current_user.id) %>
form:
<%= form_for([#user, #order]) do |f| %>
<%= f.hidden_field :user_id %>
<div class="form-group">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true, class: "form-control" %>
</div>
<% end %>
new:
<h1>New Order</h1>
<%= render 'form' %>
<%= link_to 'Back', user_orders_path(#user) %>

When you write this:
<%= form_for(#order) do |f| %>
Rails is looking for orders_path, but you don't really have such a route as you have defined your orders resource nested under the users resource. So, you have to pass both: #user and #order to the form like this:
<%= form_for([#user, #order]) do |f| %>
# your code goes here
<% end %>
If you write the form this way, then Rails will look for this path: user_orders_path which will match your defined route and will work and you won't get this error anymore:
undefined method 'orders_path' for #<#<Class:0x007faefee50a88>:0x007faefee414e8>
So, this will fix your current issue. But, there is another issue in your new.html.erb file where you currently have this:
<%= link_to 'Back', user_orders_path %>
You have to pass the #user as an argument to this method:
<%= link_to 'Back', user_orders_path(#user) %>
otherwise, it will fail again.
Hope this helps to solve your problems.

Since orders is nested on top of users, the form_for declaration will need to include both the user, and the order objects.
<%= form_for([#user, #order]) do |f| %>
Your new template will also need to have a reference to the given user.
<%= link_to 'Back', user_orders_path(#user) %>

Related

Pass new parent object id to link_to

I am trying to save parent as well as child object at the same time using accepts_nested_attributes_for
Code in controller's new method:
def new
#project = Project.new
#project.instances.build
end
and form looks like this:
<%= simple_form_for(#project) do |f| %>
<%= f.input :name %>
<%= link_to "Add New Instance", new_project_instance_path(#project), id: "new_link", remote: true %>
<% end %>
The route entry for this is:
resources :projects do
resources :instances
end
And the fields that need to be displayed instances/_form.html.erb:
<%= form.simple_fields_for :instances do |i| %>
<%= i.input :user_id %>
<%= i.input :password %>
<%= i.input :service_url %>
<% end %>
The issue here project_id being :nil, it is giving error:
No route matches {:action=>"new", :controller=>"instances", :project_id=>nil} missing required keys: [:project_id]
I need to somehow call <%= render 'cdd_instances/form', form: f %>, so that the fields get rendered below the Project details, how should I implement this?
I think your #project is null you have to pass like:
new_project_instance_path(project_id: (#project || ''))
In this case you are not able to pass non-persisted #project to create this link_to url.
I believe you are looking for something like: cocoon.
<%= simple_form_for #project do |f| %>
<%= f.input :name %>
<h3>Instances</h3>
<div id="instances">
<%= f.simple_fields_for :instances do |instance| %>
<%= render 'instance_fields', f: instance %>
<% end %>
<div class="links">
<%= link_to_add_association 'add instance', f, :instances %>
</div>
</div>
<%= f.submit %>
<% end %>
Cheers!

rails form trying to get the posts path

I cant get the syntax of this correct I'm trying to include :url => posts_path in the form_for section
<% form_for :post do |f| %>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %></p>
<p><%= f.submit %></p>
<% end %>
form_for expects an instance of a model, not a symbol:
<% form_for Post.new do |f| %>
...
<% end %>
There are a few ways to do this. Like #meager, you want to call Post.new. I usually do it in the controller, though.
posts_controller.rb
#post = Post.new
view
<% form_for #post do |f| %>
...
<% end %>
You can use a custom path if that's where you want to send the data. So if you have a special case, you can make a route for it
routes.rb
get '/special', to: 'posts#special'
then you can have a form that says...
<% form_tag special_path do |f| %>
...
<% end %>
and the params will pass as you'd think. Notice the form_tag instead of form_for though.

correct syntax for form_for url in rails

This is probably simple, I'm still coming to terms with rails syntax. What is the right syntax to pass the address_id in the url for form_for to a modified route?
This is the form - note the "address_id parameter"
<div class="one_fourth floatcenter">
<%= form_for address, :url => edit_address_path(:id => address.id), :method => :get do |f| %>
<%= content_tag(:button, :class => 'btn btn-inverse') do %> Edit Address
<% end %>
<% end %>
</div>
And this is the route I've configured:
get "edit_address/:id" => "member/addresses#edit"
Id is not being passed to the controller for some reason...
form_for address should be enough if address is a persisted object, but if it's not enough, then form_for address, url: edit_address_path(address) is what you want.
This is very simple. In place of url, you put your post method route:
<%= form_for(#post, url: super_posts_path) do |f| %>
...
<% end %>
You also call by action
<%= form_for #friend,:url=> { action: "create_friend"} do |f|%><br>
<%= f.label :u_from %>
<%= f.text_field :u_from %>
<%= f.label :u_to %>
<%= f.text_field :u_to %>
<%= f.submit%>
<% end %>

Rails: form_for routes won't display a good form

i'm new to Rails 3 and am stuck with something i think is simple to solve.
I was following the examples from Head First: Rails but came to the conclusion that they are using rails 2.
I made an html.erb file like this:
<h1>New user</h1>
<% form_for(#user, :url=>{:action=>'create'}) do |f| %>
<p>Fullname: <%= f.text_field :fullname%></p>
<p>Username: <%= f.text_field :username%></p>
<p>Email: <%= f.text_field :email%></p>
<p>Password: <%= f.text_field :password%></p>
<p><%= f.submit "Create" %></p>
<% end %>
and i want to show this form show up when i go to http://localhost:3000/users/new so i added a route like this:
resources :users
match "users/new" => "users#new"
match "users/create" => "users#create"
When i go to the address, it show's a web page with a H1-header: New User, but it doesn't show any of the other things.
What did i forget?
resources :users already contains
match "users/new" => "users#new"
match "users/create" => "users#create"
So you can safely remove them. Form doesn't display, because if you want to display result of excecution ruby code, than you should use following construction <%= %>. <% %> stands for only code execution, not for displaying.
So your new view should be like this
<h1>New user</h1>
<%= form_for(#user, :url=>{:action=>'create'}) do |f| %>
<p>Fullname: <%= f.text_field :fullname%></p>
<p>Username: <%= f.text_field :username%></p>
<p>Email: <%= f.text_field :email%></p>
<p>Password: <%= f.text_field :password%></p>
<p><%= f.submit "Create" %></p>
<% end %>
In rails 3 you need to use <%= form_for
form_for

Routing Sub-Controllers

My route looks like the following:
map.namespace(:admin) do |admin|
admin.resources :pages
end
and my controller name looks like the following:
class Admin::PagesController < ApplicationController
and my new.html.erb file looks like the following:
<% form_for(#page) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :title %>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :body %>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit "Create" %>
</p>
<% end %>
<%= link_to 'Back', :action => "index" %>
Yet I keep on getting the following error:
NoMethodError in Admin/pages#new
Showing app/views/admin/pages/new.html.erb where line #1 raised:
undefined method `pages_path' for #<ActionView::Base:0x104528000>
Extracted source (around line #1):
1: <% form_for(#page) do |f| %>
2: <%= f.error_messages %>
3: <p>
4: <%= f.label :title %>
I can't figure out why as I'm assuming the route is correct. If I try other routes then it will work until I try submitting the form, then it thinks it should be taking me back to site.com/pages which it shouldn't.
Any ideas?
Your model #page isn't aware that it's being used in a namespace like that. You can use rake routes to see all your routes for your admin namespace. You need to manually change your url path:
<% form_for(#page) do |f| %>
to
<% form_for(#page, :url => admin_pages_path) do |f| %>
Another example for when you're updating a page:
admin_page_path(#page)

Resources