i have post model, , comment model belongs post. able display post in home view corresponding home controller , home action , user/show view. thus, in home , user views, posts listed in order of creation time. able have post form in both user , home views.
the problem arises when try display comment form underneath each displayed post in home , user views. home controller/ home action has variable @post new post form displayed, making hard initiate post instance variable comment created . comment form should underneath corresponding article, leading creation of comment article.
how implement in home view? how initiate post , comment variables needed handle comment form?
here 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 unstarv website</h1> <h2> please sign use site <%= link_to "sign up", signup_path =%> now. </h2> <%= link_to "sign now!", signup_path, class: "btn btn-lg btn-primary" %> </div> <%= link_to image_tag("rails.png", alt: "unstarv logo"), '#' %> <% end %>
and here 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 end def privacy end def terms end end
and here post model, 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 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 relationships follower_id = :user_id" post.where("user_id in (#{following_ids}) or user_id = :user_id", user_id: id) end end
and here comment model:
class comment < activerecord::base belongs_to :post belongs_to :user default_scope -> { order(created_at: :desc) } end
and here 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 share common setup or constraints between actions. def set_post @post = post.find(params[:id]) end # never trust parameters scary internet, allow white list through. def post_params params.require(:post).permit(:title, :body, :picture) end end
here 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 comment</h3> <h3>post comment</h3> <%= render 'shared/comment_form' %> <% post.comments.all.each |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 app/views/shared/comment_form_html.erb , seems part of problem instance variables not correctly initialized:
<%= form_for [ @post1, @comment] |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 %>
and here trace:
actionview (4.1.8) lib/action_view/helpers/form_helper.rb:423:in `form_for' app/views/shared/_comment_form.html.erb:1:in `_app_views_shared__comment_form_html_erb__972919349_34226064' actionview (4.1.8) lib/action_view/template.rb:145:in `block in render' activesupport (4.1.8) lib/active_support/notifications.rb:161:in `instrument' actionview (4.1.8) lib/action_view/template.rb:339:in `instrument' actionview (4.1.8) lib/action_view/template.rb:143:in `render' actionview (4.1.8) lib/action_view/renderer/partial_renderer.rb:306:in `render_partial' actionview (4.1.8) lib/action_view/renderer/partial_renderer.rb:279:in `block in render' actionview (4.1.8) lib/action_view/renderer/abstract_renderer.rb:38:in `block in instrument' activesupport (4.1.8) lib/active_support/notifications.rb:159:in `block in instrument' activesupport (4.1.8)lib/active_support/notifications/instrumenter.rb:20:in `instrument' activesupport (4.1.8) lib/active_support/notifications.rb:159:in `instrument' actionview (4.1.8) lib/action_view/renderer/abstract_renderer.rb:38:in `instrument' actionview (4.1.8) lib/action_view/renderer/partial_renderer.rb:278:in `render' actionview (4.1.8) lib/action_view/renderer/renderer.rb:47:in `render_partial' actionview (4.1.8) lib/action_view/helpers/rendering_helper.rb:35:in `render' app/views/posts/_post.html.erb:22:in `_app_views_posts__post_html_erb__365860364_28803540' actionview (4.1.8) lib/action_view/template.rb:145:in `block in render' activesupport (4.1.8) lib/active_support/notifications.rb:161:in `instrument' actionview (4.1.8) lib/action_view/template.rb:339:in `instrument' actionview (4.1.8) lib/action_view/template.rb:143:in `render' actionview (4.1.8) lib/action_view/renderer/partial_renderer.rb:399:in `block in collection_with_template' actionview (4.1.8) lib/action_view/renderer/partial_renderer.rb:395:in `map'
thanks lot !!!!
in _post.html.erb
, change <%= render 'shared/comment_form' %>
render 'shared/comment_form', post: post
and in _comment_form_html.erb
, change [@post1, @comment]
[post, @comment]
edit
also need add following line homecontroller#home
@comment = comment.new
edit
the issue/question how can generate instance used in each comments form, right?
since iterating each post <%= render 'shared/feed' %>
, have post instance, accessing instance in app/views/post/_post.html.erb
, instance name post
.
when try render comment_form
, can pass parameters render
method, can send parameter called locals
or send paremeter name=value
shorcut.
if render comment_form
sending current post
can generate form based on post.
since have access post
shared/_comment_form.html.erb
, current issue how generate comment
instance, 1 way instance comment in each controller action want show feed (a bad option if used in multiple locations) , said in comment (my bad). think best option change [@post1, @comment]
(your original solution) [post, post.comments.build]
how work? since have access post
can create empty comment post
in view