My form looks like:
<%= form_for [:admin, #post] do |f|%>
<div style="width:660px;">
<%= f.text_field :title, :size => 150 %>
<br/>
<%= f.text_area :body, :id => "body", :rows => 15 %>
<br/>
<%= f.submit %>
</div>
<% end %>
the url currently is:
http://localhost:3000/admin/posts/21/edit
my rake routes for the admin post edit is:
edit_admin_post GET /admin/posts/:id/edit(.:format)
for some reason the edit_admin_post_path is returning:
/admin/post/the-post-title/edit
so I manually changed the post title to the id.
when I perform the update, i redirect:
if #post.update_attributes(params[:post])
redirect_to edit_admin_post_path #post
end
But again it is redirecting with the 'post-title' instead of the id.
why is this?
this is rails 3
NOTE:
For the show url, I wanted /post/my-post-title and not /post/234 so I'm not sure where I changed that b/c I see no reference for it in my code!
It sounds like you have something along these lines defined in your post model:
class Post < ActiveRecord::Base
def to_param
#{name}"
end
This will cause it to return just the name instead of the ID. Remove any to_params you have defined in your post model and see if that resolves it.
Change it to something like this:
def to_param
"#{id}-#{name}".downcase.gsub(/\W+/, "-").gsub(/^[-]+|[-]$/,"").strip
end
This will give you fairly clean URLs, such as: http://localhost:3000/admin/posts/21-my-post-title/edit and Post.find(21-my-post-title) works the same, essentially, as Post.find(21).
Related
I'm trying to submit a form in ruby on rails that i made, but keep getting de next error.
Ruby on Rails form: param is missing or the value is empty
my form
<%= form_for #test do |f| %>
<div class="field">
<%= f.text_field :first_name %><br>
<%= f.text_field :last_name %><br>
</div>
<div class="actions">
<%= f.submit "Create" %>
</div>
<% end %>
my controller
def new
#test = Test.new
end
def create
#test = Test.new(allow_params)
if #test.save
redirect_to 'test/index'
else
render 'test/new'
end
end
private
def allow_params
params.require(:last_name).permit(:first_name)
end
my routes
resources :test
get 'test/index'
get 'test/new'
get 'test/create'
post '/tests' => 'test#create'
Your attributes are within the testlabel, so here you should go :
def allow_params
params.require(:test).permit(:first_name, :last_name)
end
Look, this is what you form posts when you click submit:
{"utf8"=>"✓","authenticity_token"=>"...", "test"=>"first_name"=>"poldo", "last_name"=>"de poldis"},"commit"=>"Create"}
As you can see first_name and last_name are inside an hash as value of a key called test. Indeed your function allow_params expects something like this
last_name: {first_name: 'poldo'}
as you can see the param (last_name) is missing, because is inside test!
The right way is as Ben answered:
params.require(:test).permit(:first_name, :last_name)
To understand better how strong parameters works I suggest to you to check this page Api doc or even better The latest version ofthe official manual
I am creating a Rails app, and I need a form to function in one of my views and submit data to a table without the use of a scaffold (like I usually do).
Now, the place where this comment form is going to appear is in one view within the blog folder. It will need to allow the user to put in their comment, save it to the table, and then return to the same page.
While this is a pretty commonplace error, I am confused because I am specifying two things that seem critical: creating resources in my routes file for the form, and second, using a create method in my controller.
In the blog.html.erb, this happens in this form:
<%= form_for :cements do |f| %>
<div class="form-group">
<div class="field">
<%= f.label :post %><br>
<%= f.text_area :post, class: "form-control" %>
</div>
</div>
<h5 id="username">Username</h5>
<div class="form-group">
<div class="field">
<%= f.text_field :username, class: "form-control" %>
</div>
</div>
<%= f.hidden_field :slug, :id => "hiddenPicker"%>
<div class="actions">
<%= f.submit "Save", class: "btn btn-success-outline" %>
</div>
<% end %>
Then, in my controller, I have a create method that should redirect back to the original page, as I wanted.
blogs_controller.rb
class BlogsController < ActionController::Base
def index
#posts = Post.order('updated_at DESC').all
#comments = Cement.all
end
def blog
#posts = Post.where(slug: params[:id]).all
#comments = Cement.all
end
def create
#cements= Cement.new(story_params)
#cements.save
redirect_to(:back)
end
private
def story_params
params.require(:cements).permit(:username, :post, :slug)
end
end
Good news: the comment form renders in the view. Bad news: when I submit, I am getting this error: No route matches [POST] "/blog".
My expectation is this will be an issue with my Routes file; however, I have a resources method already in there:
Rails.application.routes.draw do
resources :posts
resources :cements
resources :blogs
The naming convention is the same as my controller file, so I am confused why this error is happening. Any ideas?
:cement is not an object it is just a symbol, so how rails will determine where to POST form? If you inspect your form you will see form action as /blog (current page url).
You should either do
<%= form_for :cements, url: cements_path do |f| %>
or
<%= form_for Cement.new do |f| %>
Both of above will generate form action as /cements, which will submit to CementsController create action, But I see in your case you want to submit it to BlogsController so use the appropriate routes(blogs_path). You can use url in second version also.
I'm trying to follow a tutorial on using basic AJAX to add a record to a list in place, and I'm having issues using form form_for.
Here is my code.
<%= form_for ([#product, #product.new]) do |p| %>
<p>
<%= p.label :product_part %>
<%= p.text_field :product_part%>
</p>
<p>
<%= p.submit %>
</p>
<% end %>
The error I am getting is
undefined method `new' for nil:NilClass
I understand why I am getting the error (#products hasn't been "initialized") but I have no idea how to fix this issue (I am sure it's simple). I have seen something about putting a resource in the routes file, but I do not know for sure.
If you're trying to make a form for a new product, you should (in your controller) be setting #product to an instance of a new Product:
# app/controllers/products_controller.rb
def new
#product = Product.new
end
In your view, using [#product, #product.new] makes no sense. You can't invoke new on an instance of a product. It's very unclear why you're not simply using the following, which is the correct use of form_for with a new instance of an ActiveRecord model:
form_for #product do |p|
Do this:
#app/controllers/products_controller.rb
class ProductsController < ApplicationController
def new
#product = Product.new
render :form
end
def edit
#product = Product.find params[:id]
render :form
end
end
#app/views/products/form.html.erb
<%= form_for #product, remote: true do |f| %>
<%= p.label :product_part %>
<%= p.text_field :product_part%>
<%= f.submit %>
<% end %>
This will do everything you need for both the new and edit methods (which you raised concerns about in your comments with #meagar).
This should be corroborated with the following routes (you can see why here):
#config/routes.rb
resources :products
I would say In case you need to look the form_for helper ; to understand the behavior of the method.
The method form_for It accept the argument as record, options = {}. The value of record could be a symbol object or a newly object of respective class in your case Person.new.
Second argument could be
:url, :namespace, :method, :authenticity_token, :remote , :enforce_utf8, :html
Among them :remote => true option is used as the Ajaxify your request.
form_for is a helper that assists with writing forms. form_for takes a :remote option. It works like this:
<%= form_for(#article, remote: true) do |f| %>
....
<% end %>
This will generate the following HTML:
<form accept-charset="UTF-8" action="/articles" class="new_article" data-remote="true" id="new_article" method="post">
...
</form>
Note the data-remote="true". Now, the form will be submitted by Ajax rather than by the browser's normal submit mechanism.
For more info about Form-For helper
Hope this solve your problem!!!.
I'm just trying to get some practice in with rails and have started my first project. I am creating a simple project where personal trainers can register profiles and look for work at gyms.
However when trying to navigate to the new personal trainer page this error pops up:
undefined method `pts_path' for #<#<Class:0x5d14ef8>:0x5690b68>
My personal trainer controller looks like this:
class PersonaltrainersController < ApplicationController
def index
#PT = Pt.all
end
def new
#PT = Pt.new
end
def show
end
def create
end
def contact
end
def edit
end
end
Under the routes file I have:
Rails.application.routes.draw do
resources :personaltrainers
root 'personaltrainers#index'
end
My simple_form looks like:
<%= simple_form_for #PT do |form| %>
<%= form.input :name %>
<%= form.input :age %>
<%= form.input :sex %>
<%= form.input :experience %>
<% end %>
personaltrainers_path GET /personaltrainers(.:format) personaltrainers#index
POST /personaltrainers(.:format) personaltrainers#create
new_personaltrainer_path GET /personaltrainers/new(.:format) personaltrainers#new
edit_personaltrainer_path GET /personaltrainers/:id/edit(.:format) personaltrainers#edit
personaltrainer_path GET /personaltrainers/:id(.:format) personaltrainers#show
PATCH /personaltrainers/:id(.:format) personaltrainers#update
PUT /personaltrainers/:id(.:format) personaltrainers#update
DELETE /personaltrainers/:id(.:format) personaltrainers#destroy
root_path GET / personaltrainers#index
Any help would be greatly appreciated.
Change your form code to:
<%= simple_form_for #PT, url: personaltrainers_path do |form| %>
<%= form.input :name %>
<%= form.input :age %>
<%= form.input :sex %>
<%= form.input :experience %>
<% end %>
undefined method pts_path' raised when simple_form_for trying to make a url from the model(pts it is a pluralized form of the pt model), but your routes have another resource name personaltrainers. All that you need, it's pass explicit url to the form helper, in this case it should be personaltrainers_path according your routes file.
You index and new method should be:
def index
#PT = Personaltrainer.all
end
def new
#PT = Personaltrainer.new
end
Btw, we (ruby devs) have a convention to use small case variable names, underscore in case of more_than_one_word. We use ALL_CAPS for constants.
I am making a rails application. After a user has registered (I have already created user registration with devise), they can fill out this form that will contain their profile information. I have done this several times, and i can't find what is wrong. Here is the model:
class Information < ActiveRecord::Base
belongs_to :user
end
Here is the controller:
class InformationsController < ApplicationController
def new
#information = Information.new
end
def create
#information = Information.create(params[:information])
redirect_to student_path
end
def index
end
end
And here is the view for the new action.
<div class="span6 offset3 text-center">
<h1>Edit your information</h1>
<%= simple_form_for #information do |f| %>
<%= f.input :skills %>
<%= f.input :looking_for, :label => 'What help do you need?' %>
<%= f.input :my_idea %>
<%= submit_tag "Save", :class => "btn btn-primary btn-large" %>
<% end %>
</div>
Here is the line in the routes file:
resources :informations
I get the following errors which make no sense to me:
undefined method `information_index_path' for #<#:0x007f9c00c7b3e0>
Does anyone know how to fix this? Thanks.
UPDATE:
When I did rake routes, For informations#create, which is what the form should be going to, it has a blank path. There is also informations#index, which is what I guess its going to now. How do I get it to go to informations#create if the path is blank?
Please try yanking out the comments (# signs) in lines 6 and 9 of your view. They might be messing up the ERB processing.
Can you try informations_path? See here.
The problem was with naming the resource information. As information is the same plural as it is singular, it was confusing rails. I renamed the model description and the controller descriptions_controller, and it worked.