【问题标题】:I can't cope with custom action in controller我无法处理控制器中的自定义操作
【发布时间】:2014-10-04 15:51:44
【问题描述】:

在任务控制器中我有操作:

  def destroy_all
    current_user.tasks.destroy
    redirect_to root_path
  end

我的数据库架构如下所示:

  create_table "tasks", force: true do |t|
    t.string   "content"
    t.boolean  "done"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "users_id"
  end

我有关系:Tasks belongs_to User 和 User has_many Tasks。 通过actiondestory_all我想销毁所有当前用户的任务。

但是当我点击时:

<%= link_to "delete all", { controller: 'tasks', action: 'destroy_all'}, method: 'delete' %>

什么都没有发生。用户仍然有他的所有任务。

从服务器控制台登录:

Started DELETE "/tasks/destroy_all" for 127.0.0.1 at 2014-10-04 23:29:27 +0200
Processing by TasksController#destroy_all as HTML
  Parameters: {"authenticity_token"=>"fVPDi6bczNXlfhjCDI4pJhMUm3cjv6TN1Ny/ulUO4YQ="}
  User Load (0.2ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 2  ORDER BY "users"."id" ASC LIMIT 1
Redirected to http://localhost:3000/
Completed 302 Found in 31ms (ActiveRecord: 0.2ms)


Started GET "/" for 127.0.0.1 at 2014-10-04 23:29:27 +0200
Processing by PagesController#home as HTML
  User Load (0.2ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 2  ORDER BY "users"."id" ASC LIMIT 1
  Task Load (0.1ms)  SELECT "tasks".* FROM "tasks"  WHERE "tasks"."done" = 'f' AND "tasks"."user_id" = 2
  Rendered tasks/index.html.erb within layouts/application (2.4ms)
  Rendered layouts/_userbar.html.erb (0.2ms)
  Rendered layouts/_menu.html.erb (0.1ms)
Completed 200 OK in 46ms (Views: 44.3ms | ActiveRecord: 0.3ms)

还有routes.rb文件

  resources :tasks do
    collection do
      delete :destroy_all
    end
  end

编辑:我更新了 log 和 link_to 方法并添加了 routes.rb 文件。

【问题讨论】:

  • 您是否在日志中看到任何错误或警告?
  • 没有我能识别的错误。我添加了 log sn-p。

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

首先,您的任务表需要字段“user_id”,而不是“users_id”。这可能会立即解决您的问题。

但是,您缺少 has_many 的力量!只需这样做:

current_user.tasks.destroy_all

调用“current_user.tasks”会为您获取用户任务的列表,然后您可以像我上面所做的那样对它们调用“destroy”。这更清晰,更易于阅读。

我希望这会有所帮助!

【讨论】:

  • 感谢有关 has_many 电源的建议,但它并没有解决我的问题。它仍然是一样的。我将users_id 更改为user_id。我单击“delete_all”链接,没有任何反应。服务器日志也一样。
  • 服务器日志不会完全相同,因为表已更改。至少,字段名称会有所不同。也许你应该发布更新的日志数据。
  • 您的日志 sn-p 是针对主页请求的,因此 Rails 根本不会触发您的 delete_all 操作。你的“link_to”方法生成了什么代码?
  • @Jensky link_to 有 三个 参数,而不是两个。首先是要显示的文本。第二个是它将去的路线的哈希值。第三个是额外选项的散列。 :method 选项位于 third 参数中。由于最后两个参数都是散列,因此您必须在第二个参数周围使用大括号,以便 Ruby 知道一个结束和下一个开始的位置。
  • 你需要的方法是current_user.tasks.destroy_all,不是current_user.tasks.destroy,我的错。我更新了上面的答案。
【解决方案2】:

根据您的架构,users_idString,可能是 "1""2"。但是current_user.idInteger,可能是12

在这种情况下,您将在 ActiveRecord 中找不到任何内容,因为它会查询 id 是字符串的项目,而您实际上发送的是一个整数。

因此尝试:

Task.destroy_all(users_id: current_user.id.to_s)

匹配类型。

================================

但是,您的结构很复杂,将来很难维护。我建议您执行以下操作:

  1. Task 模型中,将users_id 更改为user_id,因为它只属于一个用户。
  2. user_id的类型改为整数,因为它是id,逻辑上它只包含数值。
  3. 正如 Jaime 所建议的,在 has_many 中使用 Rails 约定并编写类似 current_user.tasks.delete_all 的内容,以保持代码简洁且更具可读性。

【讨论】:

  • 感谢您提供非常有用的建议,但这不是主要问题。因为我有破坏行动,它工作正常。当然,我尝试了您的解决方案,但没有任何改变。也许您知道如何调试它以获取有关该问题的更多信息?
  • 尝试在链接中指定一个方法,因为它默认是 GET &lt;%= link_to "delete all", controller: 'tasks', action: 'destroy_all', method: :delete %&gt;
  • 使用这种方法,您必须修改您的route.rb 并确保:destroy_all 类似于collection { delete :destroy_all },否则会出现路由错误
  • 虽然将 id 存储为字符串不是一个好主意,但 ActiveRecord 会为您进行清理并正确构建查询。这就是为什么像 "/users/123" 这样的路由会产生 params[:id] = "123",一个字符串,但 User.find(params[:id]) 仍然有效。
  • 我刚刚尝试将 get 更改为 delete 并编辑了我的帖子。它仍然无法正常工作。
猜你喜欢
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
相关资源
最近更新 更多