Trying to create comments inside posts - rails - ruby-on-rails

I'm traying to create a social media with posts and comments inside the posts.
I'm trying to link the comments to the posts but I'm not going well. I dont know if the bug is from the controllers or the views. That`s what I have:
Comment model:
class Comment < ApplicationRecord
belongs_to :user
belongs_to :post
end
post model:
class Post < ApplicationRecord
belongs_to :user
has_many :comments
end
routes:
resources :posts do
member do
resources :comments
end
end
posts controller (the idea is to show the comment form and show inside the posts, and make a kind of feed, like facebook, instagram.. ):
class PostsController < ApplicationController
def index
#posts = Post.includes(:user).order(updated_at: :desc)
#comment = Comment.new
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.user = current_user
if #post.save
redirect_to request.referrer
# redirect_to feed_users_path
else
render :new
end
end
private
def post_params
params.require(:post).permit(:content, :user)
end
end
comments controller:
class CommentsController < ApplicationController
def create
#comment = Comment.new(comment_params)
#comment.user = current_user
#comment.post = #post
if #comment.save
redirect_to request.referrer
end
end
private
def comment_params
params.require(:comment).permit(:content, :post, :user)
end
end
this is the post index:
<% #posts.each do |post| %>
<div class="row" id="post-<%= post.id %>">
<div class="col-12 post-container">
<!-- header -->
<div class="post-header d-flex justify-content-start">
<%= link_to user_path(post.user) do %>
<h5><%= post.user.first_name %> <%= post.user.last_name %></h5>
<% end %>
<p>
<%= link_to user_path(post.user) do %>
#<%= post.user.first_name %>
<% end %>
<span><%= distance_of_time_in_words(Time.now, post.created_at) %></span> ago
</p>
</div>
<!-- content -->
<div class="post-content">
<div class="post-text">
<h4><%= post.content %></h4>
</div>
</div>
<hr>
<div class="form--input">
<%= simple_form_for([#post.comment], remote: true) do |f| %>
<div class="form--input">
<%= f.input :content, input_html: { class: "form-txt py-3" }, placeholder: "What do you want to comment?", label: false %>
</div>
<div class="form--input_elements d-flex justify-content-between mx-4">
<div class="form--input_submit">
<%= f.submit "Post Comment", class: "btn btn-flat", id: "post-submit", role: "status", remote: true %>
</div>
</div>
<% end %>
</div>
</div>
</div>
<% end %>

You have a problem in the routes file, it should be like this :
resources :posts do
resources :comments
end

Related

Cloudinary images aren't displaying on live site

Pretty new to Rails, but I'm having an issue getting images to display on a live site. The images are uploaded by the user as part of creating a post, but I'm running into two issues:
The media library is not updating when an image is uploaded
On localhost the upload works fine and is displayed, however on the live site the images are not being displayed. The page loads fine but the Cloudinary image src generated doesn't point anywhere
Example:
<img class="main-post-image" src="https://res.cloudinary.com/hw2ugvhic/image/upload/vfvhamrbx0jz8rj6y17c2vy4m2gp">
New post view:
<div class="text-center mt-3">
<h1>New post</h1>
</div>
<div class = "main-form-container">
<div class= "post-form-container">
<div data-controller="multi-upload">
<%= simple_form_for [#country, #area, #post] do |f| %>
<%= f.input :title %>
<%= f.input :summary %>
<%= f.input :description, as: :rich_text_area %>
<%= f.input :category , collection: %w(bar restaurant activity nature memory) %>
<%= f.input :main_image, as: :file, label: "square image only"%>
<%= f.file_field :images, multiple: true, data: {action: "multi-upload#addFile"} %>
<div data-multi-upload-target="files"></div>
<div class = "d-flex justify-content-center">
<%= f.button :submit, class: "green-button mt-3"%>
</div>
<div class = "text-link text-center mt-2">
<%= link_to "Go back", country_area_path(#country, #area) %>
</div>
<% end %>
</div>
</div>
</div>
Posts controller:
class PostsController < ApplicationController
def new
#country = Country.find(params[:country_id])
#area = Area.find(params[:area_id])
#post = Post.new
end
def create
#country = Country.find(params[:country_id])
#area = Area.find(params[:area_id])
#post = Post.new(post_params)
#post.user = current_user
#post.area = #area
if #post.save
redirect_to country_area_path(#country, #area)
else
render :new
end
end
def show
#country = Country.find(params[:country_id])
#area = Area.find(params[:area_id])
#post = Post.find(params[:id])
end
def edit
#post = Post.find(params[:id])
#area = Area.find(params[:area_id])
#country = Country.find(params[:country_id])
end
def update
#area = Area.find(params[:area_id])
#country = Country.find(params[:country_id])
#post = Post.find(params[:id])
#post.update(post_params)
redirect_to country_area_post_path(#country, #area, #post)
end
private
def post_params
params.require(:post).permit(:title, :summary, :description, :category, :area_id, :main_image, images: [])
end
end
Post model:
class Post < ApplicationRecord
belongs_to :user
belongs_to :area
has_one_attached :main_image, dependent: :destroy
has_many_attached :images, dependent: :destroy
has_rich_text :description
validates :title, :summary, :description, :category, :main_image, presence: true
end
Area show view page (where the posts can be viewed)
<nav aria-label="breadcrumb" class="mt-2 pl-2">
<ol class="breadcrumb">
<li class="breadcrumb-item"><%= link_to "Home", root_path %></li>
<li class="breadcrumb-item"><%= link_to #country.name, country_path(#country) %></li>
<li class="breadcrumb-item active" aria-current="page"><%= #area.name %></li>
</ol>
</nav>
<% unless #posts.empty?%>
<div class = main-posts-div>
<div>
<%= "Welcome to #{#area.name}, #{#country.name}"%>
</div>
<%= link_to "New post", new_country_area_post_path(#country, #area), class: "green-button mt-3"%>
<div>
<div class="area-main-div">
<% #posts.each do |post| %>
<%= link_to country_area_post_path(#country, #area, post) do %>
<div class= "post-card">
<div>
<% if post.main_image.nil? %>
<%= image_tag("https://picsum.photos/300/300") %>
<% else %>
<%= cl_image_tag(post.main_image.key, class:"main-post-image") %>
<% end %>
</div>
<div class = "lower-post-card">
<div>
<%= post.title %>
</div>
<div>
<em><%= post.category %></em>
</div>
</div>
<% end %>
</div>
<% end %>
</div>
</div>
</div>
<% else %>
<div class="main-posts-div-blank">
<div>
<%= "Welcome to #{#area.name}, #{#country.name}. #{#area.name} is yet to be explored, please document your experience"%><br>
</div>
<%= link_to "New post", new_country_area_post_path(#country, #area), class: "green-button mt-3"%>
</div>
<% end %>
Areas controller
class AreasController < ApplicationController
def new
#area = Area.new
end
def create
#country = Country.find(params[:country_id])
#area = Area.new(area_params)
#area.country = #country
#area.save
redirect_to country_path(#country)
end
def show
#area = Area.find(params[:id])
#country = Country.find(params[:country_id])
#post = Post.new
#posts = Post.where(area_id: #area)
end
private
def area_params
params.require(:area).permit(:name, :country_id)
end
end
Steps already taken
Added Cloudinary to Heroku
Created a dotenv file with the cloudinary key
added cloudinary gem
Updated the following:
storage.yml
cloudinary:
service: Cloudinary
folder: <%= Rails.env %>
development.rb
config.active_storage.service = :cloudinary
What can I try next?
I think the only thing that might be missing is that active storage does not store the folder as part of the key e.g. post.main_image.key would be a random string but is missing folderName/<random-string> which you defined in the storage.yml file.
I believe you just need to include the folder name in the cl_image_tag(post.main_image.key, class:"main-post-image") should be cl_image_tag("folderName/"+post.main_image.key, class:"main-post-image")
There probably is a way to pass that dynamically.

Redirect the editing of nested content

Problem resolve
When I want to edit an existing section an error appears:
"Couldn't find Category with'id' ="
And my page is redirected to "http://localhost:3000/sections/1" when it should be redirected to "http://localhost:3000/categories/3/sections/1/".
sections_controller.rb
class SectionsController < ApplicationController
before_action :find_the_category
def index
#sections = #category.sections
end
def show
#section = #category.sections.find(params[:id])
end
def new
#section = Section.new
end
def edit
#section = #category.sections.find(params[:id])
end
def create
#section = #category.section.create(section_params)
flash[:success] = "Section ajouté avec succés"
if #section.save
redirect_to category_section_path(#category, #section)
end
end
def update
flash[:success] = "Section modifié avec succés"
#section = #category.sections.find(params[:id])
#section.update(section_params)
redirect_to category_section_path(#category, #section)
end
def destroy
flash[:danger] = "Section supprimé"
#section = Section.find(params[:id])
#section.destroy
redirect_to category_sections_path
end
private
def find_the_category
#category = Category.find(params[:category_id])
end
def section_params
params.require(:section).permit(:title, :content)
end
end
routes.rb
Rails.application.routes.draw do
resources :categories do
resources :sections
end
end
section#_form.html.erb
<%= bootstrap_form_for([#category, #section]) do |f| %>
<% if #section.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#section.errors.count, "error") %> prohibited this reponse from being saved:</h2>
<ul>
<% #section.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :Titre %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :Description %><br>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
category.rb
class Category < ActiveRecord::Base
# une catégorie peut avoir plusieurs questions relations has-many
has_many :questions
has_many :sections
end
section.rb
class Section < ApplicationRecord
belongs_to :category
end
Check your form url in browser, i think it wrong.
You don't provide any category to bootstrap_form_for helper, so it may generate wrong link.
Your form template must be smth like this:
bootstrap_form_for([#category, #section])

Adding Comments to multiple models

Im trying to add comments to my topics model the same way you can add comments to posts on my app. i currently have to partials for comments _comment.html.erb and _form.html.erb
_comment :
<%= content_tag :div, class: 'media', id: "comment-#{comment.id}" do %>
<div class= "media">
<div class= "media-body">
<small>
<%= comment.user.name %> commented <%= time_ago_in_words(comment.created_at) %> ago
<% if user_is_authorized_for_comment?(comment) %>
| <%= link_to "Delete", [comment.post, comment], method: :delete %>
<% end %>
</small>
<p> <%= comment.body %></p>
</div>
</div>
<% end %>
_form :
<h4>Add a comment</h4>
<%= form_for [post, comment] do |f| %>
<div class="form-group">
<%= f.label :body, class: 'sr-only' %>
<%= f.text_field :body, class: 'form-control', placeholder: "Enter a new comment" %>
</div>
<%= f.submit "Submit Comment", class: 'btn btn-default pull-right' %>
<% end %>
my topic show is :
#DISPLAY Topic comments here
<h3> Comments</h3>
<%= render #topic.comments %>
</div>
<% if current_user %>
<%= render 'comments/form', comment: Comment.new, post: #post %>
<% end %>
#------
comment controller :
def create
#post = Post.find(params[:post_id])
comment = #post.comments.new(comment_params)
comment.user = current_user
if comment.save
flash[:notice] = "Comment saved successfully."
redirect_to [#post.topic, #post]
else
flash[:alert] = "Comment failed to save."
redirect_to [#post.topic, #post]
end
end
def destroy
#post = Post.find(params[:post_id])
comment = #post.comments.find(params[:id])
if comment.destroy
flash[:notice] = "Comment was deleted"
redirect_to [#post.topic, #post]
end
end
i have updated the routes for topic comments :
resources :topics do
resources :posts, except: [:index]
resources :comments, only: [:create, :destroy]
end
my question is do i need to create a separate partial to add comments to topics or can i update my _comment partial to work for both post and topic comments . and how can i accomplish this ?
Models
You'll need a polymorphic association on the Comment model:
#app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
#app/models/topic.rb
class Topic < ActiveRecord::Base
has_many :comments, as: :commentable
end
#app/models/post.rb
class Post < ActiveRecord::Base
has_many :comments, as: :commentable
end
Controllers
This will allow you to save the comments for your various models, the controllers / flow coming secondary:
#config/routes.rb
resources :topics, :posts do
resources :comments, only: [:create, :destroy] #-> url.com/topics/:topic_id/comments
end
#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
id = params[:post_id] || params[:topic_id]
if params[:post_id]
#parent = Post.find id
elsif params[:topic_id]
#parent = Topic.find id
end
#comment = #parent.comments.find params[:id]
#comment.save
end
def destroy
#parent = params[:post_id] || params[:topic_id]
#comment = #parent.comments.new comment_params
#comment.destroy
end
private
def comment_params
params.require(:comment).permit(:x, :y)
end
end
Because you're passing the data to the comments controller, you'll only need to evaluate which #parent you're working with.
Views
For your views, you need to pass locals to your _form partial:
#app/views/posts/show.html.erb
<%= render "comments/form", locals: {parent: #post} %>
#app/views/comments/_form.html.erb
<%= form_for [parent, parent.comments.new] do |f| %>
I had this road-block as well and here is what I came up with that passed. I must first give #Richard Peck applause for getting my wheels turning, so thank you :).
Models
Did not implement a polymorphic association. Stuck with has_many and belongs_to, nothing more
Partials
_comment.html.erb
Set up the delete partial to accept "parent" as a local
<div class="media">
<div class="media-body">
<small>
<%= comment.user.name %>
commented
<%= time_ago_in_words(comment.created_at) %>
ago
<% if user_is_authorized_for_comment_via_post?(comment) %>
|
<%= link_to "Delete", [parent, comment], method: :delete %>
<% end %>
</small>
<p>
<%= comment.body %>
</p>
</div>
</div>
_form.html.erb
same idea as _comment.html.erb, see above
<h4>Add a comment</h4>
<%= form_for [parent, comment] do |f| %>
<div class="form-group">
<%= f.label :body, class: 'sr-only' %>
<%= f.text_field :body, class: 'form-control', placeholder: "Enter a new comment" %>
</div>
<%= f.submit "Submit Comment", class: 'btn btn-default pull-right' %>
<% end %>
Setting up CommentController
...
def create
# upon clicking on create, determine what param id is passed
if params[:post_id]
# if it is a post id, set instance of post id as #parent
#parent = Post.find(params[:post_id])
elsif params[:topic_id]
# if it is a topic id, set instance of topic id as #parent
#parent = Topic.find(params[:topic_id])
end
# create instance as #comment. Build/create
# comment belonging to #parent (Topic or Post)
#comment = #parent.comments.build(comment_params)
# The comment must be associated to the current user.
# A comment must have a user, and value of user within instance of #comment
# is currently nil. Set user id as current user
#comment.user = current_user
# save comment to database
if #comment.save
# direction of save through if and elsif
# Redirection depends on the comment's parent.
# .is_a? method determines if it is of a certain class. Here, is #parent
# of class Post? Is #parents is the same parent id passed through params?
if #parent.is_a?(Post) # template error with this included: (== params[:post_id])
flash[:notice] = 'Comment saved successfully'
redirect_to [#parent.topic, #parent]
# if not part of the class Post, is it a Topic? If so, save here and
# redirect to the topic after save
elsif #parent.is_a?(Topic)
flash[:notice] = 'Comment saved successfully'
redirect_to #parent
end
end
end
def destroy
comment = Comment.find(params[:id])
# #topic = Topic.find(params[:topic_id])
# topic_comment = #topic.comments.find(params[:id])
# #post = Post.find(params[:post_id])
# post_comment = #post.comments.find(params[:id])
if comment.destroy
flash[:notice] = 'Comment was deleted'
redirect_to :back
else
flash[:alert] = "Comment counld't be deleted. Try again"
redirect_to :back
end
end
...
Passing in Comments from topic/show and post/show
topic/show
Note: notice how locals are passed into the controller from here
...
<div class="row">
<%= render 'comments/form', comment: Comment.new, parent: #topic %>
</div>
<% #topic.comments.each do |comment| %>
<%= render partial: 'comments/comment', locals: { parent: #topic, comment: comment } %>
<% end %>
...
post/show
<% if current_user %>
<% #post.comments.each do |comment| %>
<%= render partial: 'comments/comment', locals: { parent: #post, comment: comment } %>
<% end %>
<% end %>
<% if current_user %>
<%= render 'comments/form', comment: Comment.new, parent: #post %>
<% end %>
Hope this helps.

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

Strong parameters with polymorphic associations

I'm building a polymorphic comment system per railscasts episode 154. I can't seem to get the strong parameters to accept the right field. In the POST action the parameters come through like this:
{"utf8"=>"✓",
"authenticity_token"=>"/yVWatJSRY1AmAqgbS4Z9S8kIlfQAKBbUeHc/5coxeM=",
"comment"=>{"content"=>"Hello"},
"commit"=>"Create Comment",
"user_id"=>"1"}
And My MVC I will post below. Does anyone know the correct way to use strong parameters in this case?
Model:
class Link < ActiveRecord::Base
has_many :votes
belongs_to :user
has_many :comments, as: :commentable
end
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
Controller
class CommentsController < ApplicationController
before_action :load_commentable
def index
#comments = #commentable.comments
end
def new
#comment = #commentable.comments.new
end
def create
#comment = #commentable.comments.new(params.require(:comment [:content]))
if #comment.save
redirect_to [#commentable, :comments], notice: "Comment created."
else
render :new
end
end
def load_commentable
resource, id = request.path.split('/')[1,2]
#commentable = resource.singularize.classify.constantize.find(id)
end
end
View
<h1>New Comment</h1>
<%= form_for [#commentable, #comment] do |f| %>
<% if #comment.errors.any? %>
<div class="error_messages">
<h2>Please correct the following errors.</h2>
<ul><% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %>
<% end %>
</ul>
</div>
<% end %>
<div class="field" >
<%= f.text_area :content, rows: 8 %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
It should't be any different then any other controller in terms of strong params.
does
#comment = #commentable.comments.new(params.require(:comment).permit(:content))
not work?

Resources