ruby-on-rails - 如何防止 rails (3.1) 为同一记录触发 2 个选择?

标签 ruby-on-rails performance forms

我有一个 CRUD 用户 Controller 。当我在浏览器中打开“用户编辑”页面时,我的日志显示如下:

Started GET "/users/1/edit" for 127.0.0.1 at 2011-06-21 20:09:37 +0200
  Processing by UsersController#edit as HTML
  Parameters: {"id"=>"1"}
  User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE
   `users`.`id` = ? LIMIT 1  [["id", 1]]
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE
   `users`.`id` = ? LIMIT 1  [["id", "1"]]

在编辑操作中,我只是调用了一个私有(private)函数 user,它返回
@user ||= User.find(params[:id])

View 如下所示:
<%= settings_title(@user.username) %>
<%= form_for @user, :html => { :multipart => true } do |f| %>
  <%= render "form", :user => @user
  <div class="action"><%= submit_tag t("users.edit.submit"), :class => "button" %></div>
<%= end %>

路由定义为resources :users do ...
任何想法如何防止第二个数据库访问将不胜感激!

更新:

似乎可以通过调用来防止第二个 DB SELECT
@user ||= User.find(params[:id].to_i) # notice the .to_i

在编辑 Action 中。我现在得到:
User Load (0.1ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = ? LIMIT 1  [["id", 1]]
CACHE (0.0ms)      SELECT `users`.* FROM `users` WHERE `users`.`id` = ? LIMIT 1

但这是正确的方法吗?您是否看到此解决方案的任何其他副作用?

最佳答案

尽管有您的#to_i 解决方法,但如果 current_user 是管理员并且可以编辑任何用户记录,那么这似乎是正确的行为。巧合的是,在这种情况下 current_user == user_to_be_edited 并且您获得了相同数据的两个数据库命中。在 current_user 正在编辑其他人的用户数据的所有其他情况下,您将不得不两次访问数据库。

但是,如果 current_user 只编辑他/她自己的数据,那么在您的 Controller 中而不是:

@user ||= User.find(params[:id])

你会使用:
@user ||= current_user

...假设在执行操作之前已经进行了用户身份验证。以这种方式,您只会在身份验证中对数据库进行一次点击。

最后一点,在前一种情况下,current_user 管理员可以编辑任何用户,如果你真的想摆脱数据库被两次命中的巧合边缘情况,你可以这样做:
@user ||= current_user.id == params[:id].to_i ? current_user : User.find(params[:id])

这样,当用户编辑他/她自己的数据时,您将避免额外的数据库命中。

关于ruby-on-rails - 如何防止 rails (3.1) 为同一记录触发 2 个选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6430028/

相关文章:

ruby-on-rails - Postgresql & Rails 3 - 数组中元素的 Update_attribute 重新排序数组..为什么?

ruby-on-rails - 使用 omniauth-google-oauth2 的 Google Oauth 登录经常失败

ruby-on-rails - Ruby:什么会导致同一代码块的执行在一遍又一遍地运行时随着时间的推移而变慢?

python - 使用 Mechanize python 登录 reddit

javascript - 我如何在 Joomla 站点中使用外部 HTML 表单?

html - 提交表格 : button or input?

ruby-on-rails - 如何在Ruby on Rails中找到上传文件的大小?

ruby-on-rails - 通过 rake 测试重置测试数据库提示 : "database configuration does not specify adapter"

linux - 在 Linux-4.4.0 中 PTI=on 性能下降

sql - SQL查询的性能