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
Related
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 :)
I have a basic blogging site in which I want to allow users to offer 'corrections' to posts (just think of it as a comment). The correction object belongs to a post, which in turn belongs to a user (for which I'm using Devise).
I would like the form to create a new correction to be nested in the page for the post,so I'm just rendering the form in posts/show.html.erb with <% render :template => "corrections/new" %>. I'm getting a 'undefined method model_name' error from the line form_for line in corrections/new.html.erb though.
Here's the form:
<% form_for [#correction, :url=> user_post_corrections_path(current_user, #post, #correction)], html: { multipart: true} do |f| %>
<div class="field">
<%= f.label :correction %>
<%= f.text_field :correction %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here's the corrections_controller:
class CorrectionsController < ApplicationController
def new
#post = Post.find(params[:post_id])
#correction = current_user.#post.corrections.build
respond_with(#correction)
end
def create
#post = Post.find(params[:post_id])
#correction = current_user.#post.corrections.build
if #correction.save
redirect_to user_post_path(current_user, #correction.post_id)
end
end
end
In my routes.rb:
resources :users do
resources :posts do
resources :corrections
end
end
Any help with this would be much appreciated.
There are several issues I can see, first off:
The form is not rendered:
The form for should be evaluated not computed so you should use <%= %> tag instead of <%%> tag, so it becomes:
<%= form_for #correction, url: user_post_corrections_path(current_user, #post, #correction), html: { multipart: true} do |f| %>
Second: You are saying form_for #correction, and you said this form is shown in posts/show, this means that the show action for the post should have the following in its controller:
#correction = Correction.new user: current_user, post: #post
This is assuming you are using the #post variable for the post show meaning you have something like
#post = Post.find params[:id]
This line is completely off
#correction = current_user.#post.corrections.build
you can just say:
#correction = Correction.new correction_params
#correction.user = current_user
#correction.post = #post
if #correction.save
redirect_to user_post_path(current_user, #correction.post_id)
end
The important part is your show action on the posts controller having the initialization of your #correction object.
This line looks off:
#correction = current_user.#post.corrections.build
#post is an instance variable, not a method on current_user
Did you intend to build a correct with the current user? The following should work:
#post.corrections.build(user: current_user)
If your corrections model has_many :users, through: :posts, then the following should work:
#post.corrections.build(users: [current_user])
EDIT
The format of your form_for is also incorrect. The url: key in form_for doesn't belong in the resource array (the first arg in your form_for)
The following modification should resolve the error, provided user_post_corrections_path takes :id, :post_id, and :correction_id
form_for #correction, url: user_post_corrections_path(current_user, #post, #correction), html: { multipart: true} do |f|
I'd also reduce your routing to two levels of nesting if possible.
Perhaps this is easier?
resources :posts do
resources :corrections
end
end
If it's implied a post belongs to the current_user then it may not be necessary to have /users in the route path.
I am getting the following error when trying to use form_for in my Rails application:
undefined method `to_key' for #<Table::ActiveRecord_Relation:0x8a09ca8>
My config/routes.rb is:
root 'welcome#index'
post 'foo', as: 'foo', to: 'welcome#index'
The controller is:
class WelcomeController < ApplicationController
def index
#tables = Table.all
end
def test
#tables = Table.all
end
end
And the welcome/index.html.erb view is:
<p>
<%= form_for #tables, :url => foo_path do |t| %>
<%= t.text_area :name %>
<% end %>
</p>
I've tried to do the url workaround that had been suggested in the documentation, but I'm still getting the same error.
Does anyone know what I am doing wrong? I would like to understand this bug a bit more so I can better deal with it.
As per your code, index is returning a collection. However your view tries to define a form for it. This is unlikely going to be succeed.
Form is for an object, not for collections.
Perhaps you can do something like
def new
#table = Table.new
end
and in new.html.erb
<%= form_for #table do |f| %>
...
<% end %>
And if you would like to stick with index.html.erb with a form. Then you have to edit your routes for index action and also in controller it should be for creating a new object.
def index
#table = Table.new
end
Hope it helps!
I see your code have 3 not true things
As RESFUL standard then:
index action always go through with get action so in route file you should define again same that:
root "wellcome#index"
get "foo", to: "wellcome#index", as: :foo
form_for usually use with model object but not collect as you use #tables, if model object not save into database form_for using to create 1 object to database, otherwise form_for using update that object
if you want create form at index action you can follow me:
def index
#tables = Table.all
#table = Table.new
end
index.html.erb file
<%= form_for #table do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
you need create tables_controller to process request from form send to server. you run: rails g controller tables
In table_controller.rb you write same as:
def create
#table = Table.new table_params
if #table.save
redirect_to root_path, notice: "success"
else
redirect_to root_path, alert: "fail"
end
end
private
def table_params
params.require(:table).permit :name
end
so that. end. Have nice day!
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
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.