Rails nested route form issue - ruby-on-rails

I have a category model that has many products. Here are the routes:
resources :categories do
resources :products
end
I see a route in rake routes for category_product_new. When i try to create a new product I get error messages that there is no route for anything I have tried.
<%= form_with(model: product, local: true) do |form| %>
Any thoughts on what I need to change with the form to allow me to submit it?

you can try with:
# app/views/products/new.html.erb
<%= form_with(model: [#category, #product], local: true) do |form| %>
// your code here
<% end %>
And in your products_controller you can try like this:
# app/controllers/products_controller.rb
class ProductsController < ApplicationController
def new
#category = Category.find(params[:category_id])
#product = Product.new
end
end
Thanks :)

Related

NoMethodError in Users#show (Ruby Rails)

I'm running into a NoMethodError in my Users#show when trying to include a form partial for submitting a task item (_form.html.erb). My other partial (_item.html.erb) is rendering properly. My item model and my user model are related to each other, user has_many :items, and item belongs_to :user.
Any and all help would be greatly appreciated!
Below is my routes.rb
Rails.application.routes.draw do
get 'welcome/index'
get 'welcome/about'
root 'users#show'
resources :users do
resources :items, only: [:new, :create]
end
devise_for :users
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Below is my terminal output
ActionView::Template::Error (undefined method `items_path' for #<#<Class:0x007fefeca61dd0>:0x007fefeca58b18>
Did you mean? items_create_path):
1: <h4> Create a new to-do item </h4>
2:
3: <%= form_for #item do |f| %>
4: <%= f.label :name %>
5: <%= f.text_field :name, class: 'form-control', placeholder: "Enter task here" %>
Items Controller
class ItemsController < ApplicationController
def new
#item = Item.new
end
def create
#item = Item.new
#item.user = current_user
#item.name = params[:item][:name]
if #item.save
flash[:notice] = "Item saved"
redirect_to #item
else
flash.now[:alert] = "Item was not created, please try again."
render :new
end
end
end
Users Controller
class UsersController < ApplicationController
def show
if !current_user.nil?
#user = current_user
#item = Item.new
#items = #user.items
else
redirect_to new_user_registration_path
end
end
end
Users#show page
<h2> Your to-do list</h2>
<div class="col-md-8">
<div class='items'>
<%= render partial: "items/item", local: { item: #item} %>
</div>
</div>
<div class="col-md-8">
<div class='new-item'>
<%= render partial: "items/form", local: { item: #item } %>
</div>
</div>
In your routes.rb file, you have items defined as a nested resource. You can check all of your routes by running this command on your terminal: rake routes.
For your routes specifically, you say:
resources :users do
resources :items, only: [:new, :create]
end
This would give you routes for GET /users/:user_id/items/new and POST /users/:user_id/items. However, in your form, it looks like you're trying to do this: <%= form_for #item do |f| %>. You don't have a route defined for an item by itself. You'll need to supply a user as well.
Try this for your form:
<%= form_for [#user, #item] do |f| %>
And something like this in your ItemsController:
class ItemsController
def new
#user = current_user
#item = Item.new
end
end
Your items route is nested under users. therefore you have to pass both to the form_for - a user and an item.
Something like this will probably work:
<%= form_for(current_user, #item) do |f| %>

No route matches [PATCH] "/persons"

I'm new to the ruby. He saw such a mistake, he looked through a lot of articles, I do everything exactly as instructed, but nothing comes out. With Create everything is in order but on the update swears.
my action:
...
def edit
#person = Person.find(params[:id])
end
def update
#person = Person.find(params[:id])
#person.update_attributes(person_params)
if #person.errors.empty?
redirect_to #person
else
render 'edit'
end
end
private
def person_params
params.require(:person).permit(:number, :family, :name, :patronymic, :other)
end
my views:
<h1>Редактировать личность</h1>
<%= form_for #person, url: persons_path do |f| %>
<p>Номер</p>
<p><%= f.text_field :number %></p>
...
<p><%= f.submit "изменить базу" %></p>
<% end %>
and router:
Rails.application.routes.draw do
resources :persons
end
You don't need to pass , url: persons_path, since persons is resource, form_for #person will figure out that it has to go to update action.
<%= form_for #person do |f| %>
should be fine.
If you still do need to pass the url, it should be url: person_path(#person), html: {method: "patch"})
Read more about this topic in Rails Edge guide -
http://guides.rubyonrails.org/v4.1/form_helpers.html#relying-on-record-identification
Note: As #engineersmnky also pointed, your config/routes.rb should traditionally have resources :people instead. Resource is specified in pluralized form.
If you generate scaffold with Rails - rails g scaffold People name:string, you will see that you get:
model - person.rb
controller - people_controller.rb
route helper - resources :people

url for Rails form for the resource of the third level

I have resources:
resources :categories do
resources :subcategories do
resources :products do
resources :comments
end
end
end
My controller, which generates view with a form for a creating comments for a product:
def show
#product = Product.find(params[:id])
#category = Category.find(params[:category_id])
#subcategory = Subcategory.find(params[:subcategory_id])
end
How to write path in a template tag for the controller Comments#create
I tried this, but it does not works:
<%= form_for category_subcategory_product_comment(#category, #subcategory, #product) do |f| %>
...
<% end %>
You can try
<%= form_for [#category, #subcategory, #products,#comments] do |f| %>
Don't forget to initialise the #comments in your controller:
#comments = Comment.new()

rails 4 edit for with different controller

I am having the following form in my profile/edit.html.erb
<%= form_for #customer, url: {controller: :customer, action: :update} do |f| %>
<%= f.text_field :username, value: #customer.username%>
<%= f.submit 'Update' %>
<% end %>
And in my customer controller i have following method
def edit
#customer = Customer.find session[:customer_id]
end
def update
#customer.update(customer_params)
end
private
private
def customer_params
params[:customer]
end
When i submit the form getting route error
No route matches [PATCH] "/customer/update"
I have added following line in route.rb then too facing same error
resources :profiles
resources :customers
Your update action never defines #customer before you use the update method. Try something like this in your update action:
#customer = Customer.find session[:customer_id]
#customer.update(customer_params)
Also, your customer params is not set correctly. To get it to permit the items in the form, use the following:
def profile_params
params.require(:customer).permit(:username)
end
The easiest way to debug issues like these is to look at the output of 'rake routes' and see if the URL you are trying to call is present in the output.
If I have to take a guess...it seems like you will need to pass in the ID of the customer in the patch request..something like /customer/1/update where 1 is the id of the customer in your database
EDIT : actually just take out the url part of the form_for. I think that is what is throwing off rails. So your form_for should look like
<%= form_for #customer do |f| %>
change controller: :customer to controller: :customers

Rails 4 Routing Error - no rout matches [POST] "/categories/new"

While learning Rails 4 I stuck while trying to add categories to posts of my simple blog. I have generated model, ran the migration and added a controller. No matter what I do now when trying to create a category, I keep running into same mistake: no route matches [POST], which is weird, as I seem to have all the code in place. Please help!
categories controller
class CategoriesController < ApplicationController
def index
#categories = Category.all
end
def new
#category = Category.new
end
def create
#category = Category.new(category_params)
#category.save
redirect_to new_category_path, alert: "Category created!"
end
def show
#category = Category.find(params[:id])
end
def destroy
#category = Category.find(params[:id])
#category.destroy
redirect_to categories_path
end
private
def category_params
params.require(:category).permit(:name)
end
end
routes.rb
Blog::Application.routes.draw do
get 'tags/:tag', to: 'posts#index', as: :tag
resources :categories
resources :posts do
resources :comments
end
root 'welcome#index'
end
category.rb
class Category < ActiveRecord::Base
validates :name, presence: true
has_many :posts
end
new.html.erb
<%= form_for :category do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
/categories/new
No route matches [POST] "/categories/new"
You should have in your view
<%= form_for #category do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
#category object is used by form_for method to figure out form url.
If you pass only Symbol to form_for method, without specifying url explicitly, form will be generated with url being the current url.
Although the #category works, if you read a bit further you will see that they will explain why the your code sends No route matches [POST] "/categories/new".
The guide actually explains that you need to specify the url: posts_path for the form to use the right route.
There's one problem with this form though. If you inspect the HTML
that is generated, by viewing the source of the page, you will see
that the action attribute for the form is pointing at /posts/new. This
is a problem because this route goes to the very page that you're on
right at the moment, and that route should only be used to display the
form for a new post.
The form needs to use a different URL in order to go somewhere else.
This can be done quite simply with the :url option of form_for.
Typically in Rails, the action that is used for new form submissions
like this is called "create", and so the form should be pointed to
that action.
Edit the form_for line inside app/views/posts/new.html.erb to look
like this:
<%= form_for :post, url: posts_path do |f| %>
In this example, the
posts_path helper is passed to the :url option. What Rails will do
with this is that it will point the form to the create action of the
current controller, the PostsController, and will send a POST request
to that route.

Resources