Rails 请教大家关于使用 default_scope 遇到的一个问题

ghn645568344 · 2017年02月22日 · 最后由 5swords 回复于 2017年02月23日 · 2033 次阅读
class Article < ActiveRecord::Base
    mount_uploader  :img, ShareUploader
    default_scope -> {where( :status => 0 )}
end

在 Article 中为了省事用了 default_scope,当 status=1 时,修改 img 图片字段报

---------------------
  Article Load (7.4ms)  SELECT  `articles`.* FROM `articles`  ORDER BY `articles`.`id` ASC LIMIT 1
   (5.1ms)  BEGIN
  Article Load (5.6ms)  SELECT  `articles`.* FROM `articles` WHERE `articles`.`status` = 0 AND `articles`.`id` = 1 LIMIT 1
   (5.0ms)  ROLLBACK
Completed 404 Not Found in 200ms (ActiveRecord: 124.4ms)

ActiveRecord::RecordNotFound (Couldn't find Article with 'id'=1 [WHERE `articles`.`status` = ?]):
  app/controllers/admins/article_controller.rb:58:in `up_article'


  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/actionpack-4.2.5.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (5.8ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/actionpack-4.2.5.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.8ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/actionpack-4.2.5.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/actionpack-4.2.5.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (19.4ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/web-console-2.3.0/lib/web_console/templates/_markup.html.erb (0.5ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/web-console-2.3.0/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.2ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/web-console-2.3.0/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.3ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/web-console-2.3.0/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.7ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/web-console-2.3.0/lib/web_console/templates/console.js.erb within layouts/javascript (15.1ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/web-console-2.3.0/lib/web_console/templates/main.js.erb within layouts/javascript (0.2ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/web-console-2.3.0/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.3ms)
  Rendered /home/haonan/.rvm/gems/ruby-2.1.4/gems/web-console-2.3.0/lib/web_console/templates/index.html.erb (29.2ms)



下面是执行的代码

puts "---------------------"
a = Article.unscoped.where(:id=>params[:id],:status=>article.status).unscoped.first#.update(:status=>article.status,:img=>params[:img])
a.img = params[:img]
a.save

不知道是怎么回事,明明使用了 unscoped,但是还是一直报找不到的错误,请教大家了

@ghn645568344 已经给出了错误 ActiveRecord::RecordNotFound (Couldn't find Article with 'id'=1,找不到 id = 1 的记录,并不是 default_scope 的问题

xfstart07 回复

找不到的原因是代码还是执行了 default_scope,但是我已经使用了 unscoped,不应该再去执行 default_scope

ghn645568344 回复

Article.unscoped.where(:id=>params[:id],:status=>article.status).unscoped.first 你的代码为什么会调用 2 次 unscoped

xfstart07 回复

测试的多加了一个看看效果😷

我设置了一个default_scope { where(role_id: 1) }

2.3.3 :001 > Account.all
  Account Load (0.3ms)  SELECT `accounts`.* FROM `accounts` WHERE `accounts`.`role_id` = 1

2.3.3 :002 > Account.where(role_id: 2).unscoped
  Account Load (0.4ms)  SELECT `accounts`.* FROM `accounts`

unscoped 是没有问题的,一般这种错误是需要先看看数据有没有问题

xfstart07 回复

这样是没问题,但是加上 mount_uploader 存储图片就不行了,很郁闷的现象

其实最好不要用 default_scope

huacnlee 回复

请教大神🙏 那该用什么里

ghn645568344 回复

定义一个普通 scope 用的时候基于那个 scope,例如 Post.publish

加一个 enum status:[]

default_scope 留给 gem 或者你项目的 lib 使用,比如软删除的实现方法就是通过设置 default_scope 的,你这边再做就会冲突

我用 unscope(:where)

需要 登录 后方可回复, 如果你还没有账号请 注册新账号