我的控制器是 - 持久地 - 在Rails中发送错误的params [:id] ?!

时间:2012-07-26 13:31:48

标签: ruby-on-rails params

我是Ruby on Rails&amp;的新手。到网络编程。 在我的应用程序中,我有两个模型; has_many :users的理事会和belongs_to :directorate的用户。 在创建新用户时,我使用new.html.erb表单中的<%= f.collection_select(:directorate_id,Directorate.all, :id, :name) %>将新用户分配到特定的首席执行官。但是,我想为dba建立一个用户友好的界面,列出所有董事会;并列出每个董事会旁边的所有用户,并附带一个链接,将任何用户分配到特定的董事会。

我所做的是以下内容:

在Directorate模型中,我定义了以下函数:

   def assign_user!(user)
      user.update_attributes(directorate_id: @directorate)
   end  

在董事会控制器中,我定义了以下行动:

 def assign_user
   @directorate = params[:directorate]
   assign_user! params[:user]
   redirect_to directorates_url
 end

现在,directorates / index.html.erb包含以下内容:

    <h1>Listing directorates</h1>

<table>
  <tr>
    <th>Name</th>
    <th>Info</th>
  </tr>

<% @directorates.each do |directorate| %>
  <tr>
    <td><%= directorate.name %></td>
    <td><%= directorate.info %></td>

    <td><%= link_to 'Show', directorate %></td>
    <td><%= link_to 'Edit', edit_directorate_path(directorate) %></td>
    <td><%= link_to 'Destroy', directorate, confirm: 'Are you sure?', method: :delete %></td>
    <%= @directorate = directorate%>
<%= render 'users_form' %>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New Directorate', new_directorate_path %>

和-users_form.html.erb包含以下表单(应该列出每个董事会旁边的所有用户,以及将任何用户分配到某个董事会的链接):

    <h1>Listing Users</h1>

    <table>
      <tr>
        <th>User Name</th>
      </tr>

      <% @users.each do |user| %>
      <tr>

        <td><%= user.username %></td>

        <td><%= link_to 'Assign to Current Directorate', {controller: 'directorates', action: 'assign_user', directorate: @directorate, user: user}, :method => :put %></td>
      </tr>
      <% end %>
    </table>

<br />

在列出董事会时,问题就出现了问题。点击“分配到当前董事会”我收到以下错误:

http://127.0.0.1:3000/directorates/assign_user?directorate=4&user=5

ActiveRecord::RecordNotFound in DirectoratesController#update

Couldn't find Directorate with id=assign_user
Rails.root: /home/ehab/sites/IAMS

Application Trace | Framework Trace | Full Trace
app/controllers/directorates_controller.rb:61:in `update'
Request

Parameters:

{"_method"=>"put",
 "authenticity_token"=>"L5tz3hv2IW0meE79qUq0/tjfGKwDlpC23hOeAWtmTvk=",
 "directorate"=>"4",
 "user"=>"5",
 "id"=>"assign_user"}

很明显,params正在提交我不想要的“id”=&gt;“assign_user”,我想要的是“id”=&gt;“directorate.id”(上例中为4)。我该怎么做才能解决这个问题?!

1 个答案:

答案 0 :(得分:2)

首先,您的路由应该说assign_user是某个member对象上的directorate方法:

resources :directorates do
  member do
    put :assign_user
  end
end

第二,你说你在assign_user!模型中定义Directorate,在assign_user中定义DirectoratesController,但两种方法都暗示它们共享相同的对象状态,如实例变量@directorate这不是真的

您的控制器方法assign_user应该看起来像

def assign_user
  @directorate = Directorate.find params[:id]
  @user        = User.find params[:user_id]

  @directorate.assign_user! @user
end

和模型方法应该看起来像

def assign_user!(user)
  user.update_attributes(directorate_id: self.id)
end

甚至我会切换到而不是告诉Directorate更改用户的属性,而是告诉User将自己分配给控制器想要的任何内容。

最后一位是指定用户到首长级的链接:

link_to 'Assign to Current Directorate',
  assign_user_directorates_path(@directorate, :user_id => user)

上面的0行代码测试了语法正确性,不要复制粘贴,阅读和理解