在rails中将id传递给form_with

Ant*_*ger 1 ruby haml ruby-on-rails

对于一个大学团体项目,我们正在创建一个 Rails 应用程序,可以在其中创建、访问大学课程等。

该项目的要求之一是“课程协调员必须能够将用户设置为给定课程的标记者”。为了解决这个问题,有一个角色表,它存储 user_id、course_id 和角色(在本例中为“Marker”)。

我创建了一个视图,课程协调员可以在其中从所有用户中选择一个用户并将其设置为标记。这发生在课程/分配标记页面上。该页面的控制器方法如下所示:

def assign_marker
    @users = User.enrolled_users
    @course = Course.find(params[:id])
end
Run Code Online (Sandbox Code Playgroud)

在这里,enrolled_users 仅返回所有非管理员用户(这有效),params[:id] 是 course_id。如果我使用看跌期权,我可以看到它具有正确的值,所以这一切都有效。

我的问题发生在我处理 post 请求的函数中:

def add_marker

    Role.assign_marker(params[:user_id], params[:id])           

    # Flash
    flash[:notice] = "#{User.find(params[:user_id]).username} was assigned as Marker to #{Course.find(params[:id]).courseName}"

    # Refresh
    redirect_back(fallback_location: root_path)

end
Run Code Online (Sandbox Code Playgroud)

提交表单后,我发现 add_marker 将 params[:id] 视为空白。下面是我在 haml 中的表单(对应于 allocate_marker 函数)

= form_with url: 'assign_marker', :id => "#{@course.id}" do |f|
  .row
    .input-field

      -# Display username in selection & store id as parameter
      = f.collection_select(:user_id, @users, :id, :username, :include_blank => true)

      %label Users

 = button_tag "Set as Marker", {:class => "waves-effect waves-light btn"} 
Run Code Online (Sandbox Code Playgroud)

如果我将 #{@course.id} 放置在视图中的任何位置,我可以看到显示的正确的 course_id。我尝试在 form_with 中设置 id,如上所示,因为这就是我对 form_tag 所做的事情。显然这不起作用,并且 add_marker 没有通过 params[:id] 看到它。

另外,我的上述 get 和 post 请求的路线如下:

get 'courses/assign_marker', :to => 'courses#assign_marker'
post 'courses/assign_marker', :to => 'courses#add_marker'
Run Code Online (Sandbox Code Playgroud)

我对 Rails 相当陌生,所以我可能错过了一些非常明显的东西。任何帮助将非常感激 :)。谢谢

Jua*_*tes 5

:id => "#{@course.id}"不起作用的原因是因为它只是用于设置 HTML id 属性,您可以在此处查看更多信息

最好的解决方案是使用嵌套路由。假设你resources :courses在某个地方config/routes.rb可以这样声明:

resources :courses do
  member do
    get :assign_marker
    post :add_marker
  end
end
Run Code Online (Sandbox Code Playgroud)

这将生成以下路由:

GET  /courses/:id/assign_marker
POST /courses/:id/add_marker
Run Code Online (Sandbox Code Playgroud)

然后您可以像这样引用它们的路径:

assign_marker_course(@course)
add_marker_course(@course)
Run Code Online (Sandbox Code Playgroud)

另一种解决方案,听起来可能更简单,但实际上并不是“Rails 方式”,是将 id 添加为隐藏字段,如下所示:

= f.hidden_field :id, value: @course.id
Run Code Online (Sandbox Code Playgroud)