Ruby on Rails: undefined method "comments" for nil:NilClass - ruby-on-rails

I am developing an app with users where they each have set of microposts displayed on their pages. I am trying to add comments to these microposts. Every time I visit localhost:3000/users/(user_id_#)
I get this error: undefined method `comments' for nil:NilClass
This error only comes when the user has microposts to show. Otherwise it just shows their blank page. The error comes from this view for app/views/users/show.html.erb This view renders this partial, where the error occurs in line 13.
<li>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
confirm: "You sure?",
title: micropost.content %>
<% end %>
<h2>Comments</h2>
<% micropost.comments.each do |comment| %>
<p>
<b>Commenter:</b>
<%= comment.commenter %>
</p>
<p>
<b>Comment:</b>
<%= comment.body %>
</p>
<% end %>
<h3>Add a comment:</h3>
<%= form_for([micropost, micropost.comments.build]) do |f| %>
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
</li>
Here is my comment.rb file
class Comment < ActiveRecord::Base
belongs_to :micropost
attr_accessible :body, :user_id
end
and my micropost.rb file
class Micropost < ActiveRecord::Base
attr_accessible :content
belongs_to :user
has_many :comments
validates :content, presence: true, length: { maximum: 140 }
validates :user_id, presence: true
end
and my comments_controller.rb
class CommentsController < ApplicationController
def create
#micropost = Micropost.find(params[:micropost_id])
#comment = #micropost.comments.create(params[:comment])
redirect_to micropost_path(#micropost)
end
end
and finally my microposts_controller.rb
class MicropostsController < ApplicationController
before_filter :signed_in_user
before_filter :correct_user, only: :destroy
def create
#micropost = current_user.microposts.build(params[:micropost])
if #micropost.save
flash[:success] = "Micropost created!"
redirect_to root_path
else
#feed_items = []
render 'static_pages/home'
end
end
def new
#micropost = Micropost.new(params[:micropost])
end
def show
#micropost = Micropost.find(params[:id])
end
def destroy
#micropost.destroy
redirect_back_or root_path
end
private
def correct_user
#micropost = current_user.microposts.find_by_id(params[:id])
redirect_to root_path if #micropost.nil?
end
end
class CommentsController < ApplicationController
def create
#micropost = Micropost.find(params[:micropost_id])
#comment = #micropost.comments.create(params[:comment])
redirect_to micropost_path(#micropost)
end
end
also here is the users_controller.rb
class UsersController < ApplicationController
before_filter :signed_in_user,
only: [:index, :edit, :update, :destroy, :following, :followers]
before_filter :correct_user, only: [:edit, :update]
before_filter :admin_user, only: :destroy
def index
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#micropost = #user.microposts.first
#comment = Comment.new
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def edit
end
def update
if #user.update_attributes(params[:user])
flash[:success] = "Profile updated"
sign_in #user
redirect_to #user
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to users_path
end
def following
#title = "Following"
#user = User.find(params[:id])
#users = #user.followed_users.paginate(page: params[:page])
render 'show_follow'
end
def followers
#title = "Followers"
#user = User.find(params[:id])
#users = #user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
end
from the error it sounds like the #micropost isnt being initialized in the microposts_controller.rb file under def show. but I think it is? What am I doing wrong? Thanks
also here is app/views/users/show.html.erb
<% provide(:title, #user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</section>
</aside>
<div class="span8">
<%= render 'follow_form' if signed_in? %>
<% if #user.microposts.any? %>
<h3>Microposts (<%= #user.microposts.count %>)</h3>
<ol class="microposts">
<%= render #microposts %>
</ol>
<%= will_paginate #microposts %>
<% end %>
</div>
</div>

I suspect the error is here in your partial:
<% #micropost.comments.each do |comment| %>
I am assuming that you are iterating over #microposts and passing each micro post to your partial as micropost. In the above line you are using the instance variable #micropost when you should be using the local micropost.
Update: and also here:
<%= form_for([#micropost, #micropost.comments.build]) do |f| %> –

Could you try to change this #microposts = #user.microposts.paginate(page: params[:page]) into this #micropost = #user.microposts.first and see if it works ?
I think since the partial is rendered in the context of users#show that why #micropost is nil.
This is not an answer, I just want to comment but I don't have enough reputation points.

Related

Rails validation error message is not displaying

I have tried multiple methods to show error message from views, but it is not appearing.
<%= form_for #article do |f| %>
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% #article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
_form.html.erb
<center>
<h1>New article</h1>
<%= render 'form' %>
<%= link_to 'Back', articles_path %>
</center>
new.html.erb
class Article < ActiveRecord::Base
#attr_accessible :title, :text
has_many :comments, dependent: :destroy
validates :title, presence: true
end
article.rb
Rails.application.routes.draw do
root "articles#index"
resources :articles do
resources :comments
end
end
routes.rb
class ArticlesController < ApplicationController
http_basic_authenticate_with name: "deba", password: "12345", except: [:index, :show]
def index
#articles = Article.all
end
def new
#article = Article.new
end
def show
#article = Article.find(params[:id])
end
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render 'new' ##article.errors, status: :unprocessable_entity
end
end
def edit
#article = Article.find(params[:id])
end
def update
#article = Article.find(params[:id])
if #article.update(article_params)
redirect_to #article
else
render 'edit'
end
end
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to articles_path
end
private
def article_params
params.require(:article).permit(:title, :text)
end
end
articles_controller.rb
Kindly help me. I tried it, validation is working as I can check that if there is no title it redirect me to new page without saving it but not appearing the error messages.
The problem is with your redirecting - it causes the browser to initiate a new request and then you lose all the data (including the instance variables where the error is stored). Instead of redirecting you should simply render the "new" partial when article is invalid.
You haven't posted your controller code but this should give you a direction
if #article.save
# whatever you wanna do if its valid
else
render "new" # render the view without redirecting
end
try to edit your controller:
class ArticlesController < ApplicationController
before_action :initialize_article, only: [:new, :create]
...
def new
end
def create
if #article.update(article_params)
redirect_to #article
else
render :new
end
end
....
private
def initialize_article
#article ||= Article.new
end
end

unable to show details of a user if their username is clicked on

Im making a twitter clone. on my tweets index, i currently have the username of the person who tweeted next to their tweet. I want it so when you click on the name, it goes to their profile page. However at the moment when i click on any of the usernames it takes you to the current users profile. Any way to solve this? thanks
<h1>TWEETS</h1>
<% if user_signed_in? %>
<%= simple_form_for [ #user ,#tweet], id: "form-submit" do |f| %>
<%= f.input :content, label: "Tweet" %>
<%= f.button :submit, class: "btn btn-danger" %>
<% end %>
<% end %>
<br>
<% #tweets.each do |tweet| %>
<ul>
<li>
<%= tweet.created_at.strftime("%B %d %Y, %l:%M%P") %> <br>
<%= tweet.content %>
<%= link_to tweet.user.username, user_path(#user) %>
</li>
</ul>
<% end %>
class TweetsController < ApplicationController
# before_action :authenticate_user!, :except => [:index, :show]
def index
#tweets = Tweet.all.order("created_at DESC")
#tweet = Tweet.new
#user = current_user
end
def show
#tweet = Tweet.find(params[:id])
end
def new
# #tweet = Tweet.new
end
def create
# #user = current_user
#user = User.find(params[:user_id])
#tweet = Tweet.new(tweet_params)
#tweet.user = #user
if #tweet.save
redirect_to user_tweets_path
end
end
def edit
#tweet = Tweet.find(params[:id])
end
def update
#tweet = Tweet.find(params[:id])
#tweet.update(tweet_params)
redirect_to tweets_path
end
private
def tweet_params
params.require(:tweet).permit(:content)
end
end
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
end
<h1>Profile of <%= #user.username %> </h1>
You are referencing the wrong user in your list.
# change this, your #user is defined in controller as current_user
<%= link_to tweet.user.username, user_path(#user) %>
# to
<%= link_to tweet.user.username, user_path(tweet.user) %>
Side note: you also shouldn't need to set #user if you set an application level helper method for current_user

How do I make sure each post in the Post feed shown in the home page has all its comments displayed under it?

I have a Post model, and a Comment model that belongs to Post. I was able to display the Post in the home view corresponding to the home controller and home action and the User/show view. Thus, in the home and user views, the posts are listed in order of creation time. I was also able to have a post form in both the user and home views and a comment form in the home and user views.
The problem arises when I try to display the comment underneath each displayed Post in the home and user views. How can I list the comments associate with each post under the post in the home and user views ?
How do I make sure the comments in the databased are listed under the corresponding post ?
Here is my comments controller:
class CommentsController < ApplicationController
def index
#comments =Comment.all.paginate(page: params[:page])
end
def show
#comment = Comment.find(params[:id])
#post = #Comment.post
end
def new
end
def create
#comment = Comment.new(comment_params)
if #comment.save
flash[:success] = "Comment created"
redirect_to :back
else
render 'new'
end
end
def edit
#comment = Comment.find(params[:id])
end
def update
#comment = comment.find(params[:id])
if #comment.update_attributes(comment_params)
flash[:success] = "Comment updated"
redirect_to #comment.post
else
render 'edit'
end
end
def destroy
Comment.find(params[:id]).destroy
flash[:success] = "Comment deleted"
redirect_to users_url
end
private
def comment_params
params.require(:comment).permit(:author_name, :body)
end
end
Here is my home view: app/views/home/home.html.erb:
<% if logged_in? %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<hr/>
<br/>
<section class="stats">
<%= render 'shared/stats' %>
</section>
<section class="post_form">
<%= render 'shared/post_form' %>
</section>
</aside>
<div class="col-md-8">
<h3>Post Feed</h3>
<%= render 'shared/feed' %>
</div>
</div>
<% else %>
<div class="center jumbotron">
<h1>Welcome to the Unstarv website</h1>
<h2>
Please sign up now to use this site
<%= link_to "Sign Up", signup_path =%>
now.
</h2>
<%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %>
</div>
<%= link_to image_tag("rails.png", alt: "unstarv logo"), '#' %>
<% end %>
And here is my home controller:
class HomeController < ApplicationController
def home
if logged_in?
#post = current_user.posts.build
#feed_items = current_user.feed.paginate(page: params[:page])
end
end
def about
end
def privacy
end
def terms
end
end
And here is my Post model, the relevant part:
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
default_scope -> { order(created_at: :desc) }
mount_uploader :picture, PictureUploader
end
The relevant part of my User model:
class User < ActiveRecord::Base
attr_accessor :remember_token
before_save { self.email = email.downcase }
has_many :posts, dependent: :destroy
has_many :comments
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
validates :username, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }, allow_blank: true
def feed
following_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id"
Post.where("user_id IN (#{following_ids}) OR user_id = :user_id", user_id: id)
end
end
And here is my Comment model:
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
default_scope -> { order(created_at: :desc) }
end
And here is the post controller:
class PostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
def index
#posts = Post.all
end
def show
#post = Post.find(params[:id])
#comment = Comment.new
#comment.post_id = #post.id
#comments = #post.comments.all
end
def new
#post = Post.new
end
def create
#post = current_user.posts.build(post_params)
if #post.save
flash[:success] = "Post created!"
redirect_to root_url
else
#feed_items = []
render 'home/home'
end
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
#post.update(post_params)
flash.notice = "Post '#{#post.title}' Updated!"
render 'home/home '
end
def update
#post = Post.find(params[:id])
#post.update(post_params)
flash.notice = "Post '#{#post.title}' Updated!"
redirect_to root_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :body, :picture)
end
end
Here is my app/views/post/_post.html.erb file,
<li id="post-<%= post.id %>">
<span class="user"><%= link_to post.user.username, post.user %></span>
<span class="content">
<%= post.title %>
<%= post.body %>
<%= image_tag post.picture.url if post.picture? %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(post.created_at) %> ago.
<% if current_user?(post.user) %>
<%= link_to "delete", post, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</span>
<section>
<h2>Your Comments here</h2>
<h3>Post a Comment</h3>
<h3>Post a Comment</h3>
<%= render 'shared/comment_form' %>
<% post.comments.all.each do |comment| %>
<h4><small>Comment by</small> <%= comment.post.user.username %></h4>
<p class="comment"><%= comment.body %></p>
<p><small>Posted <%= distance_of_time_in_words(Time.now, comment.created_at) %> ago</small></p>
<br/>
<%end%>
</li>
And here is my app/views/shared/comment_form_html.erb , which works fine:
<%= form_for [ post, post.comments.build] do |f| %>
<p>
<%= f.label :body, "Your Comment" %><br/>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit 'Submit' . method="post", class: 'btn btn-primary' %>
</p>
<% end %>
Here is my app/views/posts/_post.html.erb
<li id="post-<%= post.id %>">
<span class="user"><%= link_to post.user.username, post.user %></span>
<span class="content">
<%= post.title %>
<%= post.body %>
<%= image_tag post.picture.url if post.picture? %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(post.created_at) %> ago.
<% if current_user?(post.user) %>
<%= link_to "delete", post, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</span>
<h2>Comments</h2>
<h3>Post a Comment</h3>
<%= render 'shared/comment_form', post: post %>
<h3>Comments (<%= post.comments.size %>)</h3>
<% post.comments.each do |comment| %>
<h4><small>Comment by</small> <%= comment.post.user.username %></h4>
<p class="comment"><%= comment.body %></p>
<p>Posted <%= distance_of_time_in_words(Time.now, comment.created_at) %> ago</p>
</li>
<br/>
<%end%>
Thanks a lot for your help !!!!
The issue is related in how you are creating the comments.
With the actual code, the comment does not belong to any post so in your comments_controller change create action to something like:
def create
post = Post.find(params[:post_id])
#comment = post.comments.build(comment_params)
if #comment.save
flash[:success] = "Comment created"
redirect_to :back
else
render 'new'
end
end

Ruby on Rails / How to automatically add foreign key to my "comment" model?

I generate 3 models: "User", "Article" and "Comment", and the "Comment" model have foreign key "user_id" and "article_id". However I can't automatically add "article_id" when I want to create an comment to a specific article in view.
In rails console, I can add it successfully by using
comment = Comment.new(:content => "Great post")
comment.user = user
comment.article = Article.find(1)
comment.save
I tried to write some code in my controller, but is doesn't work
articles_controller.rb
class ArticlesController < ApplicationController
before_filter :signed_in_user, only: [:create, :destroy]
before_filter :correct_user, only: :destroy
def index
#articles = Article.all
end
def show
#article = Article.find(params[:id])
#comment = Comment.new()
end
def create
#article = current_user.articles.build(params[:article])
if #article.save
flash[:success] = "Article created!"
redirect_to root_url
else
render 'static_pages/home'
end
end
def destroy
#article.destroy
redirect_to current_user
end
private
def correct_user
#article = current_user.articles.find_by_id(params[:id])
redirect_to root_url if #article.nil?
end
end
comments_controller.rb
class CommentsController < ApplicationController
before_filter :signed_in_user, only: [:create, :destroy]
before_filter :correct_user, only: :destroy
def create
#comment = current_user.comments.build(params[:comment])
if #comment.save
flash[:success] = "Comment created!"
redirect_to articles_url
else
render 'static_pages/home'
end
end
def destroy
#comment.destroy
redirect_to current_user
end
private
def correct_user
#comment = current_user.comments.find_by_id(params[:id])
redirect_to root_url if #comment.nil?
end
end
in view files
/articles/show.html file render a partial file "_comment_form.html.erb"
_comment_form.html.erb
<%= form_for(#comment) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose your comment..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
I can add some new lines to manually add article_id to the comments table. But it is not a good way.
<% #comment.article_id = #article.id %>
<%= form_for(#comment) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :article_id %>
<%= f.text_field :article_id %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose your comment..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
How can I do?
Thank you so much.
changed _comment_form.html.erb
# views/comments/_comment_form.html.erb
<%= form_for[:articles, #comment] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose your comment..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
The error:
SyntaxError in Articles#show
Showing F:/RailsProject/project/gamespace/app/views/comments/_comment_form.html.erb where line #2 raised:
F:/RailsProject/project/gamespace/app/views/comments/_comment_form.html.erb:2: syntax error, unexpected keyword_do_block, expecting keyword_end
...orm_for[:articles, #comment] do |f| #output_buffer.safe_conc...
... ^
F:/RailsProject/project/gamespace/app/views/comments/_comment_form.html.erb:9: syntax error, unexpected keyword_ensure, expecting $end
Extracted source (around line #2):
1:
2: <%= form_for[:articles, #comment] do |f| %>
3: <%= render 'shared/error_messages', object: f.object %>
4: <div class="field">
5: <%= f.text_area :content, placeholder: "Compose your comment..." %>
# comments_controller.rb
class CommentsController < ApplicationController
before_filter :signed_in_user, only: [:create, :destroy]
before_filter :correct_user, only: :destroy
def create
#comment = Comment.new(comment_params)
#comment.article_id = params[:id]
if #comment.save
flash[:success] = "Comment created!"
redirect_to articles_url
else
render 'static_pages/home'
end
end
def destroy
#comment.destroy
redirect_to current_user
end
private
def correct_user
#comment = current_user.comments.find_by_id(params[:id])
redirect_to root_url if #comment.nil?
end
def comment_params
params.require(:comment).permit(:content).merge(:user_id => current_user.id, :article_id => params[:id])
end
end
Error:
TypeError in CommentsController#create
can't convert Symbol into String
Rails.root: F:/RailsProject/project/gamespace
Application Trace | Framework Trace | Full Trace
app/controllers/comments_controller.rb:33:in `comment_params'
app/controllers/comments_controller.rb:7:in `create'
This error occurred while loading the following files:
comment
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"ybkPs+c2068AZIIqCNJz1epBtS4L1zgT/vU9LL2Fs+E=",
"comment"=>{"content"=>"sdfadfa"},
"commit"=>"Post",
"article_id"=>"10"}
-------------------------------------------------------------------------------
Solution:
# comments_controller.rb
def create
comment = current_user.comments.build(params[:comment])
comment.article = Article.find(params[:article_id])
comment.save
end
use hidden_field method
# views/_comments_form.html.erb
<%= form_for [#article, #comment] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.hidden_field :article_id, :value => #article.id %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose your comment..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
I was going to write a long post here, but I actually agree with Monk_code - you'll be better to inject the foreign_key into the new record rather than playing around with any tricks
#app/controllers/comments_controller.rb
def create
comment = Comment.new(comment_params)
comment.article_id = params[:id]
comment.save
end
OR
#app/controllers/comments_controller.rb
def create
comment = Comment.new(comment_params)
comment.save
end
private
def comment_params
params.require(:comment).permit(:content).merge(:user_id => current_user.id, :article_id => params[:id])
end
Associative Data
The problem I can see is that your model will probably look like this:
#app/models/comment.rb
Class Comment > ActiveRecord::Base
belongs_to :article
belongs_to :user
end
If this is the case, you have to remember that you're saving data which is dependent on a parent model. As it's a dependency, it will not automatically know the foreign key, meaning you'll have to assign it yourself
If you were saving a new Article, you'll be able to pass accepts_nested_attributes_for or even just create a comment record after_create
Correctly Designing Your Application
My solution is to use the params[:id] you'll likely have in place as a result of using
resources :articles do
resources :comments
end
This means every comment will have to be created on an article's page, thus allowing you to use the params[:id] variable when you create a new record
Update
class CommentsController < ApplicationController
before_filter :signed_in_user, only: [:create, :destroy]
#before_filter :correct_user, only: :destroy
def new
#comment = Comment.new
end
def create
#comment = Comment.new(comment_params)
if #comment.save
flash[:success] = "Comment created!"
redirect_to articles_url
else
render 'static_pages/home'
end
end
def destroy
#comment.destroy
redirect_to current_user
end
private
def comment_params
params.require(:comment).permit(:content).merge(:user_id => current_user.id, :article_id => params[:article_id])
end
end
you need something that
comment = Comment.new(:content => "Great post")
comment.user = user
comment.articles << Article.find(1)
comment.save
use << instead =
read this and about has_many

New post - First argument in form cannot contain nil or be empty

This is error I'm getting when I click on "New Post:
First argument in form cannot contain nil or be empty
My PostController:
class PostsController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.all
end
def show
end
def edit
end
def update
#post.update(post_params)
redirect_to posts_path
end
def new
if user_signed_in?
#post = Post.new
else
flash[:alert] = ":("
end
end
def create
#post = Post.new(post_params)
#post.user_id = current_user.id
#post.save
redirect_to posts_path
end
def destroy
if user_signed_in?
#post.destroy!
else
flash[:alert] = ":("
end
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:body)
end
def set_user
#post = Post.find(params[:id])
end
end
and posts#index:
<% #posts.each do |post| %>
<%= post.body %>
<%= link_to 'Show', post %>
<%= link_to 'Edit', edit_post_path(post) %>
<%= link_to 'Delete', post, method: :delete %>
<br>
_form.html.erb
<%= form_for(#post) do |f| %>
<div class="field">
<%= f.label :body %><br>
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
you should check your "new.html.erb" or "_form.html.erb" file. to see if the "form_for" method is correctly called.
If you are using devise, You can get this by adding a before action:
before_action :authenticate_user!, only: [:new]
and you new action as:
def new
#post = Post.new
end

Resources