Hope that this files is enough to solve the problem. All is working I just can't save the post.
routes:
Rails.application.routes.draw do
root 'posts#index'
resources :posts
end
post_controller:
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(post_params)
if #post.save
flash[:notice] = "Successfully created post!"
redirect_to post_path(#post)
else
flash[:alert] = "Error creating new post!"
render :new
end
end
private
def post_params
params.require(:post).permit(:author, :title, :summary, :body)
end
end
Make sure your Post form code starts like this:
<%= form_for(#post) do |f| %>
You do "GET" for post#new and a "POST" for post#create.
The new action is designed to return the form required to "POST" to the create action. You don't post to the new action.
Related
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
Right now in my rails 4 app after the user submits a post I want the app to redirect/render the show view, but right now it just goes to the create view. Here is my Posts controller:
class PostsController < ApplicationController
def show
#post = Post.find(params[:id]) # show
end
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
private
def post_params
params.require(:post).permit(:Title, :Body) #whatsoever your post has
end
#redirect_to post_path(#post)
if #post.save
redirect_to #post.find(params[:id])
else
render :new
end
end
Here are my routes:
Rails.application.routes.draw do
root :to => "pages#index"
devise_for :users
resources :users
resources :pages
resources :posts
end
Thanks for your help.
Looks like there's a few bits of code in wrong places - end statements, and your final if statement at the bottom, which doesn't seem to be in any method.
Something like this should work:
class PostsController < ApplicationController
def show
#post = Post.find(params[:id]) # show
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post.find(params[:id])
else
render :new
end
end
private
def post_params
params.require(:post).permit(:title, :body) #whatsoever your post has
end
end
First, the redirect is wrong. It should be simply:
redirect_to #post
After fixing that, it could be re-rendering because there was an error validating the #post. If #post.save fails the form will be re-rendered, but the URL will stay pointed at the create action.
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.
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
I am having a bit of trouble displaying the most recent created comments based from the time/date that they were created in my views/post/show.htmlerb file. I just got my posts_controller to display the most recent created posts from the def index action but now in my def show action the following code doesn't work:
#comment_date_order = Comment.find(params[:id]).comments.order('created_at DESC')
this is my full posts_controller.rb file:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :vote]
before_action :require_user, only: [:new, :create, :edit, :update, :vote]
before_action :require_creator, only:[:edit, :update]
def index
#posts = Post.page(params[:page]).order('created_at DESC').per_page(10)
end
def show
#comment = Comment.new
#comment_date_order = Post.find(params[:id]).comments.order('created_at DESC')
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.creator = current_user
if #post.save
flash[:notice] = "You created a post!"
redirect_to posts_path
else
render :new
end
end
def edit
end
def update
#post = Post.find(params[:id])
if #post.update(post_params)
flash[:notice] = "You updated the post!"
redirect_to post_path(#post)
else
render :edit
end
end
def vote
Vote.create(voteable: #post, creator: current_user, vote: params[:vote])
respond_to do |format|
format.js { render :vote } # Renders views/posts/vote.js.erb
end
end
private
def post_params
params.require(:post).permit(:url, :title, :description)
end
def set_post
#post = Post.find(params[:id])
end
def require_creator
access_denied if #post.creator != current_user
end
end
comments_controller.erb file:
class CommentsController < ApplicationController
before_action :require_user
def create
#post = Post.find(params[:post_id])
#comment = Comment.new(params.require(:comment).permit(:body))
#comment.post = #post
#comment.creator = current_user
if #comment.save
flash[:notice] = "Your comment was created!"
redirect_to post_path(#post)
else
render 'posts/show'
end
end
def edit
#comment = Comment.find(params[:id])
#post = Post.find(params[:post_id])
end
def update
#comment = Comment.find(params[:id])
if #comment.update(comment_params)
flash[:notice] = "You updated your comment!"
redirect_to post_path(#post)
else
render :edit
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
def set_comment
#comment = Comment.find(params[:id])
end
end
First you would need a relation between Post and Comment if you dont already.
I would just create a def in the Post model.
class Post < ActiveRecord::Base
has_many :comments
def newest_comments
self.comments.order('created_at DESC')
end
end
That way you could also make a oldest_post method and uses it directly in the view
<%= #post.newest_post.each do |comment| %>
Also as best practice. Try and not to create too many instance vars in your controller. Remember fat models, skinny controllers.