我生成了3个模型:“User”,“Article”和“Comment”,而“Comment”模型有外键“user_id”和“article_id”。但是,当我想在视图中为特定文章创建评论时,我无法自动添加“article_id”。
在rails控制台中,我可以使用
成功添加它comment = Comment.new(:content => "Great post")
comment.user = user
comment.article = Article.find(1)
comment.save
我试图在我的控制器中编写一些代码但是不起作用
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
在视图文件中 /articles/show.html文件呈现部分文件“_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 %>
我可以添加一些新行来手动将article_id添加到comments表中。但这不是一个好方法。
<% @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 %>
我该怎么办? 非常感谢你。
更改了_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 %>
错误:
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
错误:
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"}
解决方案:
# comments_controller.rb
def create
comment = current_user.comments.build(params[:comment])
comment.article = Article.find(params[:article_id])
comment.save
end
使用hidden_field方法
# 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 %>
答案 0 :(得分:1)
我打算在这里写一篇很长的帖子,但我实际上同意Monk_code - 你最好将foreign_key
注入新记录而不是玩弄任何技巧
#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
关联数据
我可以看到的问题是你的模型可能看起来像这样:
#app/models/comment.rb
Class Comment > ActiveRecord::Base
belongs_to :article
belongs_to :user
end
如果是这种情况,您必须记住您正在保存依赖于父模型的数据。由于它是一个依赖项,它不会自动知道外键,这意味着你必须自己分配
如果您要保存新的Article
,则可以传递accepts_nested_attributes_for
,甚至只需创建评论记录after_create
正确设计您的应用程序
我的解决方案是使用您可能使用的params[:id]
resources :articles do
resources :comments
end
这意味着每个评论都会在文章的页面上创建,从而允许您在创建新记录时使用params[:id]
变量
<强>更新强>
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
答案 1 :(得分:0)
你需要的东西
comment = Comment.new(:content => "Great post")
comment.user = user
comment.articles << Article.find(1)
comment.save
使用<<
代替=
阅读this和about has_many