通过params检索记录会导致`id`

时间:2018-06-04 04:55:38

标签: ruby-on-rails rails-activerecord

在我的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方法可以正常工作。如何使用给定的参数正确检索课程和教授记录?

3 个答案:

答案 0 :(得分:1)

<td><%= link_to "Add Review", new_review_path(course_id: @course.id, professor_id: professor.id) %></td>

它会reviews/new.html.erb

此处您必须使用隐藏字段发送course_idprofessor_id,以便您可以在创建操作之前获取@course@professor。否则@course@professor将返回nil

  

修改后的代码: -

据我所知,在创建操作之前您不需要find_professorfind_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])

请按照上面的说法,你可以正确使用。