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 %>