标签: default-scope

default_scope在某些情况下会中断(更新|删除|销毁)_all

我相信这是Rails 3中的一个错误.我希望有人能指引我朝着正确的方向前进.下面发布的代码纯粹是为了说明这个问题.希望这不会混淆问题.

鉴于我有一个Post模型和一个Comment模型.发表has_many评论,评论发表于发帖.

在Post模型上设置default_scope,定义join()和where()关系.在这种情况下,()依赖于连接().

通常帖子不依赖于评论.再说一遍,我只想举一个简单的例子.当where()依赖于join()时,这可能是任何情况.

class Post < ActiveRecord::Base
  has_many :comments, :dependent => :destroy

  default_scope joins(:comments).where("comments.id < 999")
end

class Comment < ActiveRecord::Base
  belongs_to :post, :counter_cache => true
end
Run Code Online (Sandbox Code Playgroud)

运行以下命令:

Post.update_all(:title => Time.now)
Run Code Online (Sandbox Code Playgroud)

生成以下查询,并最终抛出ActiveRecord :: StatementInvalid:

UPDATE `posts` SET `title` = '2010-10-15 15:59:27'  WHERE (comments.id < 999)
Run Code Online (Sandbox Code Playgroud)

同样,update_all,delete_all,destroy_all的行为方式相同.当我的应用程序在尝试更新counter_cache时抱怨时,我发现了这种行为.最终深入研究update_all.

ruby-on-rails default-scope destroy

9
推荐指数
2
解决办法
1795
查看次数

Rails 3默认范围,范围与覆盖

我有一种情况,现有应用程序的行为正在发生变化,这让我头疼.

我的应用有照片.照片有一个状态:"batch", "queue", or "complete".应用中的所有现有照片都是"完整的".

99%的时间我只需要显示完整的照片,而在所有现有的代码库中,我需要每次调用照片仅限于完整的照片.

但是,在与上传和分类照片相关的屏幕中,我需要能够相当轻松地覆盖默认范围以显示批量或排队的照片.

像许多其他人一样,我需要找到一种在某些情况下轻松覆盖默认范围的方法.我看着这些问题(1,2),他们似乎并没有回答我要找的.

我希望的代码是这样的:

class Photo < ActiveRecord::Base
  ...
  default_scope where(:status=>'complete')
  scope :batch, unscoped.where(:status=>'batch')
  scope :queue, unscoped.where(:status=>'queue')
  ...
end
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用.我尝试在lambdas中包装范围方法,但这也不起作用.

我知道default_scope带有行李,但是如果我不能使用覆盖,那么我正在寻找添加scope :complete ...并且必须梳理我现有应用程序中每次调用照片并添加.complete以过滤未处理的照片.

你会如何解决这个问题?

activerecord named-scope ruby-on-rails default-scope ruby-on-rails-3

7
推荐指数
1
解决办法
1万
查看次数

Rails 3.1.3无范围范围

我已经看过很多关于这个的帖子,但似乎都没有解决我的问题.我有一个default_scope像这样的模型:

default_scope where(:is_active => true).order('LOWER(table.name)');
Run Code Online (Sandbox Code Playgroud)

我有其他(正常)范围,我想使用创建inactive范围unscoped.我想将它定义为范围,但只有在定义为类方法时才有效:

# works
def self.inactive
  unscoped { where(:is_active => false) }
end

# none of these work
scope :inactive, unscoped { where(:is_active => false) }
scope :inactive, with_exclusive_scope { where(:is_active => true) }
scope :inactive, unscoped.where(:is_active => false)
scope :inactive, lambda { unscoped { where(:is_active => false) } }
scope :inactive, unscoped { lambda { where(:is_active => false) } }
unscoped do
  scope :inactive, where(:is_active => false)
end
Run Code Online (Sandbox Code Playgroud)

有没有我错过的方法,或者我是否必须使用类方法来定义此范围?

activerecord ruby-on-rails default-scope ruby-on-rails-3.1

7
推荐指数
1
解决办法
2387
查看次数

续集中的default_scope

在ActiveRecord中,有一个default_scope类方法来指定默认范围.例如

class User < ActiveRecord::Base
  default_scope where(:deleted => false)
end

User.all # => SELECT * FROM users WHERE deleted = 0;
Run Code Online (Sandbox Code Playgroud)

我怎么能这样做Sequel::Model

编辑:

经过一些谷歌搜索后,我终于找到了一些有用的信息.

class User < Sequel::Model

  # Define some "scopes" (filters on the dataset)
  dataset_module do
    def existing
      filter(deleted: false)
    end

    def active
      filter(disabled: false)
    end
  end

  # This is the equivalent to a default_scope. Set one of the datasets
  # as the default dataset for this model.
  set_dataset(self.active)
end
Run Code Online (Sandbox Code Playgroud)

生成的查询如下所示:

User.all # => …
Run Code Online (Sandbox Code Playgroud)

ruby activerecord default-scope sequel

7
推荐指数
1
解决办法
2389
查看次数

连接表上的Default_scope

我有一个如下模型设置:

class User
  has_many :items
  has_many :words, :through => :items
end

class Item
  belongs_to :user
  belongs_to :word

  default_scope where(:active => true)
end

class Words
  has_many :items
end
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是default_scope没有应用于以下关联:

 user.words
Run Code Online (Sandbox Code Playgroud)

而不是这个SQL:

SELECT `words`.* FROM `words` INNER JOIN `items` ON `words`.id = `items`.word_id WHERE ((`items`.user_id = 1)) AND ((`items.active = 1))
Run Code Online (Sandbox Code Playgroud)

我在日志中得到这个SQL:

SELECT `words`.* FROM `words` INNER JOIN `items` ON `words`.id = `items`.word_id WHERE ((`items`.user_id = 1)) 
Run Code Online (Sandbox Code Playgroud)

我认为这是因为默认范围适用于常规模型及其子关联,但不适用于连接表.

使连接表范围在关联之间工作而不需要指定它的正确Rails方法是什么?有人存在吗?

scope ruby-on-rails has-and-belongs-to-many has-many-through default-scope

6
推荐指数
1
解决办法
2281
查看次数

应用默认范围并引用yii中的关系

我找不到太多关于在yii中将默认范围应用于模型的文档,我想知道是否有人可以解释或指出我正确的方向.

我的问题的快速版本:

是否可以向默认范围添加关系,或者默认情况下为模型上的每个AR搜索添加"with"条件?

我的问题的长版本:

我的应用程序的快速摘要:

我有两个型号,provideritem.它有:1关系,其中提供者可以有许多项目,但每个项目只能有一个提供者.

到目前为止,我有这些关系:

class Provider extends CActiveRecord
{
    ...
    public function relations()
    {
        return array(
            'items' => array(self::HAS_MANY, 'Item', 'id_provider', 'order'=>'rank DESC'),
        );
    }
    ...
}

class Item extends CActiveRecord
{
    ...
    public function relations()
    {
        return array(
            'provider' => array(self::BELONGS_TO, 'Provider', 'id_provider'),
        );
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

在我的项目模型中,我已经有了一个defaultScope来过滤掉所有离线项目(即只显示设置为的项目offline = false):

public function defaultScope()
{
    $alias = $this->getTableAlias(false,false);
    return array(
        'condition'=>"`$alias`.`offline` = false",
    );
}
Run Code Online (Sandbox Code Playgroud)

我现在要做的是,还过滤掉其提供者设置为离线的项目(即仅显示provider.offline = false当前项目旁边的项目item.offline …

relation yii default-scope scopes

5
推荐指数
1
解决办法
8922
查看次数

Rails:ActiveRecord的default_scope和类继承

我的应用不仅有用户,还有管理员和超级管理员.由于所有三个共享相同的属性,我只想使用一个具有附加属性"角色"的表,可以是"user","admin"或"super_admin":

class User < ActiveRecord::Base
 # with nickname and password
end


class Admin < User

  def power
    puts "admin rights"
  end
end


class SuperAdmin < Admin

  def superpower
    puts "I've got the #{power}!"
  end
end
Run Code Online (Sandbox Code Playgroud)

现在我想做一些事情SuperAdmin.all,只得到SuperAdmins.使用default_scope似乎让我在那里:

class SuperAdmin < Admin
  default_scope where(["role = ?", "super_admin"])

  # ...
end
Run Code Online (Sandbox Code Playgroud)

现在我也将一个default_scope添加到Admin:

class Admin < User
  default_scope where(["role = ?", "admin"])

  # ...
end
Run Code Online (Sandbox Code Playgroud)

Aaaand ... SuperAdmin.all不再返回任何内容.这是为什么?

inheritance activerecord default-scope ruby-on-rails-3.2

5
推荐指数
2
解决办法
2269
查看次数

使用偏执狂的默认范围急切加载已删除的记录

我正在使用paranoia gem 来“软删除”记录。现在,我需要为关联模型立即加载这些记录,其中一些记录可能已被删除。Paranoia 将其添加default_scope到“偏执”模型中:

default_scope :conditions => { :deleted_at => nil }
Run Code Online (Sandbox Code Playgroud)

所以实际上,我有这些(简化的)模型:

class Product
  has_many :orders
  default_scope :conditions => { :deleted_at => nil }
end

class Order
  belongs_to :product
end
Run Code Online (Sandbox Code Playgroud)

我想要实现的是在访问订单时立即加载产品:

Order.includes(:product)
Run Code Online (Sandbox Code Playgroud)

这(来自如何在 Rails3 中的关联关系上使用无作用域?)在这里不起作用:

Product.unscoped { Order.includes(:product) }
Run Code Online (Sandbox Code Playgroud)

我知道我可以创建自定义belongs_to关系来添加条件(如“渴望加载嵌套关联和作用域”),但我找不到删除现有关系的方法(如果可能的话)。

问题:如何防止将默认范围应用于急切加载查询?

ruby-on-rails eager-loading default-scope ruby-on-rails-3

5
推荐指数
1
解决办法
2867
查看次数

当 Devise 用户超出我的默认范围时,如何允许他们登录?

我有一个 Rails 4 应用程序,它使用 Devise 3.4 进行身份验证,我已经自定义了禁止用户的功能(使用简单的布尔列users.banned,默认为 false)。该User模型还有一个default_scope只返回非禁止用户的。

问题是——我仍然希望我的被禁用户能够登录,即使他们在登录后不能做任何事情。(他们基本上只是看到一个页面说“你被禁了”)。但似乎default_scope正在绊倒Devise。当您登录或调用 eg 时authenticate_user!,Devise 尝试使用基本 ActiveRecord 方法之一(如find或 )查找当前用户find_by,但不能,因为它们位于默认范围之外。因此,Devise 得出该用户不存在的结论,并且登录失败。

如何让设计忽略默认范围?

activerecord ruby-on-rails default-scope devise warden

5
推荐指数
1
解决办法
650
查看次数

覆盖active_admin form.has_many中的默认范围

给定一个带有__附件的模型Post,附件有一个隐藏的标志.在整个应用程序中,我想轻松地说post.attachments并且只获得可见的,所以我在Attachment模型中设置了一个默认范围(使用squeel):

default_scope -> { where { (hidden != true) | (hidden == nil) } } 
Run Code Online (Sandbox Code Playgroud)

但是管理页面需要能够查看帖子的所有附件,而不仅仅是可见的附件(因此您可以切换隐藏的复选框).执行此操作的默认方式(在admin/posts.rb中)使用default_scope,只允许我编辑可见的:

f.has_many :attachments do |a|
  ...
end
Run Code Online (Sandbox Code Playgroud)

我知道我可以不使用default_scope而是命名它:可见,然后到处(管理页面除外)说post.attachments.visible但我不喜欢这样做.

如何取消管理页面上的子附件?

default-scope ruby-on-rails-3 activeadmin

4
推荐指数
1
解决办法
1009
查看次数

default_scope with:joins和:select

我尝试以下列方式定义default_scope:

default_scope :joins => :product, :select => "catalog_products.*, products.*"
Run Code Online (Sandbox Code Playgroud)

我从Rails得到的是这样的:

 SELECT catalog_products.* FROM `catalog_products` INNER JOIN `products` ON `products`.id = `catalog_products`.product_id 
Run Code Online (Sandbox Code Playgroud)

当我将它定义为named_scope时,一切都很好:

named_scope :extended, :joins => :product, :select => "catalog_products.*, products.*"


SELECT catalog_products.*, products.* FROM `catalog_products` INNER JOIN `products` ON `products`.id = `catalog_products`.product_id 
Run Code Online (Sandbox Code Playgroud)

这应该是一个错误还是一个正确的行为?

我正在使用Rails 2.3.4.

谢谢!

activerecord named-scope ruby-on-rails default-scope

3
推荐指数
1
解决办法
6019
查看次数

如何在模型上放置多个默认范围?

我想知道你如何在模型上有多个默认范围(排序),例如我有一个评论模型,需要按日期和批准进行排序:

default_scope :order => 'approved ASC', :order => 'date ASC'
Run Code Online (Sandbox Code Playgroud)

那么你如何将这两种订单都放在模型上,所以我首先按批准订购,然后按日期订购.

干杯!

sql model ruby-on-rails default-scope

3
推荐指数
2
解决办法
2351
查看次数

如何向Rails范围添加多个条件?

我一直在寻找这个并且似乎无法找到答案,虽然我认为如果你对Rails比我更有经验,那应该是一个非常简单的解决方案.我正在尝试将多个default_scope条件添加到我的产品模型中.我的产品型号文件如下:

class Product < ApplicationRecord
    has_many :order_items
    default_scope { where(active: true) }
    validates :name,  presence: true, length: { maximum: 300 }
    PRICE_REGEXP = /\A\d{1,4}(\.\d{0,2})?\z/
    validates :price, presence: true,
                      numericality: true,
                      format: { with: PRICE_REGEXP }
    validates :description, presence: true, length: { maximum: 1000 }, 
                            allow_nil: true
end
Run Code Online (Sandbox Code Playgroud)

我想补充一点

default_scope -> { order(created_at: desc) }
Run Code Online (Sandbox Code Playgroud)

所以产品索引页面上的新产品的格式是最新的.我在任何时候执行以下操作时都会收到语法错误消息:

default_scope -> { order(created_at: desc) }, { where(active: true) }
Run Code Online (Sandbox Code Playgroud)

要么

default_scope -> { order(created_at: desc), where(active: true) }
Run Code Online (Sandbox Code Playgroud)

要么

default_scope -> { order(created_at: desc) …
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails default-scope ruby-on-rails-4 ruby-on-rails-5

3
推荐指数
1
解决办法
1765
查看次数