I am working on ruby on rails , I am trying to update my data
def update
#post = Post.find(params[:id])
if #post.update_attributes(params[:post])
redirect_to post_path,:notice =>"post has been updated"
else
render "edit"
end
end
it's not updating and the error coming is :-
ActiveModel::ForbiddenAttributesError in PostsController#update
Help me !
You cannot just update values based on params[:post], you will have to whitelist them using strong params.
Basically white post params like this in the controller
def post_params
params.require(:post).permit(:title, :description)
end
And then in the controller
def update
#post = Post.find(params[:id])
if #post.update_attributes(post_params)
redirect_to post_path,:notice =>"post has been updated"
else
render "edit"
end
end
private
def post_params
params.require(:post).permit(:title, :description)
end
Related
This question already has answers here:
Forbidden Attributes Error in Rails 4 when encountering a situation where one would have used attr_accessible in earlier versions of Rails
(5 answers)
Closed 4 years ago.
I am createing simple ruby blog app I am updating a post but it's showing thi type error
error
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post
puts "******************dd*********************"
puts params[:post]
puts "**************************************"
#post.update_attributes(params[:post])
redirect_to post_path, :notice => "you post has been updated"
else
render "edit"
end
end
but when I using this
#post.update_attributes({"title"=>"2nd", "body"=>"this is second post body", "category_id"=>"2"})
it is work
You should use strong parameters, Rails prevent you from assigning unfiltered params coming from outside world for security reasons.
def update
# ...
#post.update_attributes(post_params)
# ...
end
# ...
private
def post_params
params.require(:post).permit(:title, :body, :category_id)
end
Attributes should be whitelisted for updating.
Below is the code:
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post
#post.update_attributes(post_params)
redirect_to post_path, :notice => "you post has been updated"
else
render "edit"
end
end
private
def post_params
params.require(:post).permit(:title, :body, :category_id)
end
ActiveModel::ForbiddenAttributesError is only raised if you pass unsanitized objects to the record update call.
#post.update_attributes(params[:post]) # This would be an issue
Post.where(params[:post]) # This would not
#post.update_attributes(post_params) # Neither would this
def post_params
params.require(:post).permit(:title, :body, :category_id)
end
I am new to Ruby on Rails and I was trying to create a simple app when I ended up having a ActiveModel::ForbiddenAttributesError
class PostsController < ApplicationController
def index
#posts = Post.all
end
def show
#post = Post.find(params[:id])
end
def new
#post =Post.new
end
def create
#post = Post.new(params[:post])
if #post.save
redirect_to post_path,:notice=>"success"
else
render "new"
end
end
def edit
end
def update
end
def destroy
end
private
def post_params
params.require(:post).permit(:Title, :content)
end
end
I have seen a similar error here but the solution for that did not fix my issue.
My version of rails is 4.2.0.
The error displayed is
You can't use that params[:post] hash (or any params[*] hash) directly in any mass-assignment method, you need to use a permit call so Rails knows you've checked it and to allow it.
So, change your Post.new to #post = Post.new(post_params)
Change #post = Post.new(params[:post]) to #post = Post.new(post_params).
I think that
def create
#post = Post.new post_params
if #post.save
flash[:success] = "Created new post"
redirect_to #post
else
render 'new'
end
end
def create
#post = Post.new(posts_params)
if #post.save
redirect_to post_path,:notice=>"success"
else
render "new"
end
end
private
def posts_params
params.require(:post).permit(:Title, :content)
end
I am trying to access the database and enter some info. it gives me an error saying "undefined local variable or method `post_params' for #< PostsController:0x00000005aad728>"
i know this has been answered here.
but i tried following what they did, and it just does not work, can someone help me with this?
class PostsController < ApplicationController
def index
#post = Post.all
end
def show
#post = Post.find(params[:id])
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to posts_path, :notice => "Your post was saved"
else
render ="new"
end
private
def post_params
params.require(:post).permit(:title, :content)
end
end
end
Your end for create method is enclosing the private keyword and post_params method. Update it as:
def create
#post = Post.new(post_params)
if #post.save
redirect_to posts_path, :notice => "Your post was saved"
else
render ="new"
end
end # Add end here
private
def post_params
params.require(:post).permit(:title, :content)
end
end # Remove this end
You define your post_params method inside of create method. Move it outside of it and all will be working.
class PostsController < ApplicationController
def new
end
def create
#post = Post.new(params[:post])
#post.save
redirect_to #post
end
private
def post_params
params.require(:post).permit(:title, :text)
end
def show
#post = Post.find(params[:id])
end
def index
#posts=Post.all
end
end
You'll need to improve your code (you've set your index and show methods as private!):
class PostsController < ApplicationController
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.save
redirect_to #post
end
def show
#post = Post.find(params[:id])
end
def index
#posts=Post.all
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
As per the strong params documenation, you need to call the private method with your strong params inside in order to pass them
Because you're not using it.
Replace params[:post] with your method post_params.
Make post_params method as private method but not other method
private
def post_params
params.require(:post).permit(:title, :text)
end
Call it where you want to use like this.
def create
#post = Post.new(post_params)
#post.save
redirect_to #post
end
My error message is "wrong number of arguments (0 for 1)"
for this line: #post = Post.destroy in my
PostsController#destroy
I have a model which is post.rb
My Posts Controller is here
class PostsController < ApplicationController
def new
#post = Post.new
end
def index
#posts = Post.all
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post
else
render 'new'
end
end
def post_params
params.require(:post).permit(:title, :text)
end
def show
#post = Post.find(params[:id])
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title, :text))
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post = Post.destroy
redirect_to posts_path
end
end
In my view I have this code:
<%= link_to 'Destroy', post_path(post),
method: :delete, data: { confirm: 'Are you sure?' } %>
This is what it says I have for the parameters in the request
{"_method"=>"delete",
"authenticity_token"=>"Pzsnxv8pt+34KIKpYqfZquDv3UpihkINGSJxomMNsW4=",
"id"=>"3"}
What in the heck am I doing wrong??
You need to provide the ID to the destroy method:
Post.destroy(params[:id])
As stated here: http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-destroy
Here is your problem:
#post = Post.destroy
In Ruby you can destroy object in this way:
#post.destroy
Another tip: when you are using variables just inside model or controller, declare them as locals by not adding # in front of them and use # just for variables that you need to use globally. Learn more about that here:
In what circumstances should I use instance variables instead of other variable types?
Precisely what the error says.
You can:
Call destroy on an instance with no argument, e.g., #post.destroy
On the class with an id, e.g., Post.destroy(an_id)
I guess you wish to write:
#post.destroy