在我的ReviewsController
中,我在before_action
中调用了两个私有方法:
def find_course
@course = Course.where(:id=>params[:course_id]).first
end
def find_professor
@professor = Professor.where(:id=>params[:professor_id]).first
end
我通过params查询Course
,出于某种原因,我的创建方法中出现nil:NilClass`错误的undefined method
id':
def create
@review = Review.new(review_params)
@review.course_id = @course.id
@review.professor_id = @professor.id
@review.user_id = current_user.id
if @review.save
redirect_to course_path(@course)
else
render 'new'
end
end
正在以部分形式调用create方法:
<%= simple_form_for @review do |f| %>
<%= f.input :rating %>
<%= f.input :comment %>
<%= f.button :submit %>
<% end %>
表格通过课程的展示模板中的链接显示:
<h2><%= @course.name %></h2>
<table class="table">
<thead>
<tr>
<th scope="col">Professors</th>
<th scope="col">Reviews</th>
</tr>
</thead>
<tbody>
<% @course.professors.each do |professor| %>
<tr>
<td><%= professor.name %></td>
<td><%= link_to "Add Review", new_review_path(course_id: @course.id, professor_id: professor.id) %></td>
</tr>
<% end %>
</tbody>
</table>
new_review_path
中定义的routes.rb
:
resources :reviews, path_names: { new: 'course/:course_id/professor/:professor_id' }
由于某些奇怪的原因,如果我将@course = Course.where(:id=>params[:course_id]).first
替换为@course = Course.find(7)
(7是现有课程的id),则create方法可以正常工作。如何使用给定的参数正确检索课程和教授记录?
答案 0 :(得分:1)
<td><%= link_to "Add Review", new_review_path(course_id: @course.id, professor_id: professor.id) %></td>
它会reviews/new.html.erb
,
此处您必须使用隐藏字段发送course_id
和professor_id
,以便您可以在创建操作之前获取@course
和@professor
。否则@course
和@professor
将返回nil
。
修改后的代码: -
据我所知,在创建操作之前您不需要find_professor
和find_course
,因为这两个字段已经在Review
模型中,所以只需将其传递给form_for包装并在strong_params中将它们全部传递出来
<%= simple_form_for @review do |f| %>
<%= f.input :rating %>
<%= f.input :comment %>
<%= f.hidden_field :course_id, :value => params[:course_id]%>
<%= f.hidden_field :professor_id, :value => params[:professor_id] %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.button :submit %>
<% end %>
控制器中的
def create
@review = Review.new(review_params)
if @review.save
course = @review.course
#redirect_to course_path(@course)
redirect_to course_path(course)
else
render 'new'
end
end
private
def review_params
params.require(:review).permit(:rating,:comment,:course_id, :professor_id, :user_id)
end
答案 1 :(得分:0)
在调用.id
之前,您需要检查课程和教授对象是否已被提取并存在例如:
if @course && @professor
@review = Review.new(review_params)
@review.course_id = @course.id
@review.professor_id = @professor.id
@review.user_id = current_user.id
if @review.save
redirect_to course_path(@course)
else
render 'new'
end
end
答案 2 :(得分:-2)
使用是好习惯,
@course = Course.find(params[:course_id])
@professor = Professor.find(params[:professor_id])
请按照上面的说法,你可以正确使用。