我有一个Rails应用程序,它有三个主要模型: Qn,Ans和Comments 。我已经使用1级深度嵌套资源做得很好,但是这三个资源是深度嵌套(注释是浅层嵌套的)并且它们都显示在一个单独的视图中< / em>,这让它非常混乱。
在类似:http://localhost:3000/questions/2的网址中,用户可以看到使用循环显示的所有 @ question.answers 。在每个答案中,用户可以看到使用循环显示的 answer.comments 。在每个答案下方,用户还可以提交新评论。
但是在尝试多次实现1)循环显示所有注释和2)表单的新评论后,我总是得到一些错误:
undefined method `model_name' for {:url=>"/questions/4/answers/2/comments/new"}:Hash
所以我尝试传递参数 @commentable 而不是回答,或指向特定控制器和操作等等,但这些方法都没有奏效。我猜我的控制器开头有问题,但我似乎无法弄清楚是什么。
routes.rb(top ommited)
# Resources
resources :sessions
resources :users
resources :bookmarks # to be implemented later
resources :questions do
resources :answers do
resources :comments, shallow: true
end
end
问题模型
class Question < ApplicationRecord
has_many :answers
has_many :bookmarks #later
end
答案型号:
class Answer < ApplicationRecord
belongs_to :question
has_many :comments, as: :commentable
has_many :likes, as: :likeable
validates :answercontent, length: {minimum: 50}
end
评论模型:
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
show.html.erb(QuestionsController)
<% @question.answers.each do |answer| %>
// ommited
<!-- Comments -->
<% answer.comments.each do |comment| %>
<%= comment.content %>
<br>
<% end %>
<!-- Submit new comment -->
<%= form_for(url: new_question_answer_comment_path, comment: {answer_id: answer.id, question_id: @question.id}) do |f| %>
<%= f.text_area :content %>
<%= f.submit "Submit" %>
<% end %>
<% end %>
QuestionsController(新的,创建,破坏为了简洁而省略)
class QuestionsController < ApplicationController
def index
@questions = Question.all
end
def show
@question = Question.find(params[:id])
@answers = Answer.all
# Delete only appears when num_ans is 0
@deletable = (current_user== User.find(@question.user_id)) && (@question.answers.all.size==0)
end
private
def question_params
params.require(:question).permit(:picture_url, :country, :educational_level, :topic)
end
end
AnswersController(为简洁起见,编辑,更新,销毁)
class AnswersController < ApplicationController
def create
@question = Question.find(params[:question_id])
@answer = @question.answers.create(answer_params)
@answer.question_id = @question.id
@answer.user_id = current_user.id
if @answer.save
redirect_to @question
else
render :new
end
end
private
def answer_params
params.require(:answer).permit(:user_id, :question_id, :answercontent)
end
end
CommentsController
class CommentsController < ApplicationController
before_filter: load_commentable
def index
@commentable = Answer.find(params[:answer_id])
@comments = @commentable.comments
end
def new
@comment = @commentable.comments.new
end
def create
@comment = @commentable.comments.new(params[:comment])
if @comment.save
redirect_to @commentable
else
render :new
end
end
# From RailsCast ep.154
private
def load_commentable
resource, id = request.path.split('/')[1,2]
@commentable = resource.singularize.classify.constantize.find(id)
end
end
路线 现在很乱,所以我只会发表评论的地方:
question_answer_comments GET /questions/:question_id/answers/:answer_id/comments(.:format) comments#index
POST /questions/:question_id/answers/:answer_id/comments(.:format) comments#create
new_question_answer_comment GET /questions/:question_id/answers/:answer_id/comments/new(.:format) comments#new
edit_comment GET /comments/:id/edit(.:format) comments#edit
comment GET /comments/:id(.:format) comments#show
PATCH /comments/:id(.:format) comments#update
PUT /comments/:id(.:format) comments#update
DELETE /comments/:id(.:format) comments#destroy
提前感谢您的帮助。
更新
为您提供有关我尝试的解决方案的更多信息: 1.传递两个参数:
<%= form_for([answer, @comment], url: new_question_answer_comment_path(answer.id, @question.id)) do |f| %>
给我:
First argument in form cannot contain nil or be empty
所以我认为问题是回答或 @commentable 是零。但我也在循环和控制器中指定了它。那么我还能尝试什么呢?
答案 0 :(得分:1)
form_for
期望记录为第一个参数,在您的情况下,它应该是评论实例。另外 的值,因为您创建新评论, route < / em>应为new_question_answer_comment_path
期望question_id
和answer_id
键question_answer_comments
而不是new_question_answer_comment
,因此您的form_for
应为
<%= form_for Comment.new,url: question_answer_comments_path(@question,answer) do |f| %>
<%= f.text_area :content %>
<%= f.submit "Submit" %>
<% end %>
或只是
<%= form_for [Comment.new,@question,answer] do |f| %>
<%= f.text_area :content %>
<%= f.submit "Submit" %>
<% end %>