在我的Rails应用程序中有一个默认范围,如下所示:
default_scope order: 'external_updated_at DESC'
Run Code Online (Sandbox Code Playgroud)
我现在升级到Rails 4,当然,我得到以下弃用警告"不推荐使用散列调用#scope或#default_scope.请使用包含范围的lambda.".我已经成功转换了我的其他范围,但我不知道default_scope的语法应该是什么.这不起作用:
default_scope, -> { order: 'external_updated_at' }
Run Code Online (Sandbox Code Playgroud) 假设我有一个Post模型和一个Comment模型.使用常见模式,Post has_many Comments.
如果Comment设置了default_scope:
default_scope where("deleted_at IS NULL")
Run Code Online (Sandbox Code Playgroud)
无论范围如何,如何轻松检索帖子上的所有评论?这会产生无效结果:
Post.first.comments.unscoped
Run Code Online (Sandbox Code Playgroud)
这会生成以下查询:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments;
Run Code Online (Sandbox Code Playgroud)
代替:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments WHERE post_id = 1;
Run Code Online (Sandbox Code Playgroud)
运行:
Post.first.comments
Run Code Online (Sandbox Code Playgroud)
生产:
SELECT * FROM posts LIMIT 1;
SELECT * FROM comments WHERE deleted_at IS NULL AND post_id = 1;
Run Code Online (Sandbox Code Playgroud)
我理解uncoped删除所有现有范围的基本原则,但是它不应该知道并保持关联范围吗?
拉取所有评论的最佳方式是什么?
在我的Post.rb模型中,我有 default_scope :conditions => {:deleted => 'false'}
但如果我试图跑Post.find(:all, :conditions => "deleted='false'")
,它将不会返回任何东西.就像default_scope优先于所有内容一样.
我想要它,以便当我这样做Post.find()
时不会返回已删除的帖子,但我也希望能够在需要时访问它们.在我的查询或我的Rails模型中需要更改什么?
谢谢.
我的模型有default_scope(:order =>'created_at')我的测试(rspec,factory girl,shoulda等)是:
require 'spec/spec_helper.rb'
describe CatMembership do
context "is valid" do
subject { Factory.build(:cat_membership) }
it { should be_valid }
it { should belong_to :cat}
it { should belong_to :cat_group}
it { should have_db_column(:start_date)}
it { should have_db_column(:end_date)}
end
end
Run Code Online (Sandbox Code Playgroud) 我知道named_scope已经改为rails 3中的范围.
我如何在rails 3中执行default_scope,我有一个很好的谷歌,但没有找到默认范围.
在使用ActiveAdmin注册的资源中,我为模型定义了以下default_scope:
default_scope :order => 'activities.updated_at DESC'
Run Code Online (Sandbox Code Playgroud)
这显然阻止我通过单击列标题来更改资源索引页面上的排序.有没有办法保持这个默认范围,但让Active Admin排序工作?
所以基本上我有两个班,书和作者.书籍可以有多个作者,作者可以有多本书.书籍具有以下默认范围.
default_scope :order => "publish_at DESC"
Run Code Online (Sandbox Code Playgroud)
在作者展示页面上,我想列出与该作者相关的所有书籍,所以我说以下内容......
@author = Author.find(params[:id])
@books = @author.books
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都很好.作者#show页面列出了按出版日期排序的所有属于该作者的书籍.
我也在研究一种能够按照书籍的受欢迎程度排序的宝石.
@books = @author.books.sort_by_popularity
Run Code Online (Sandbox Code Playgroud)
问题是每当它尝试排序时,default_scope总是会妨碍.如果我试图取消它之前它将摆脱作者关系并返回数据库中的每本书.例如
@books = @author.books.unscoped.sort_by_popularity # returns all books in database
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以使用ActiveRelation except()方法 做这样的事情(看起来它应该工作,但事实并非如此.它忽略了顺序,只是当它是default_scope命令时)
def sort_by_popularity
self.except(:order).do_some_joining_magic.order('popularity ASC')
# |------------| |---------------------|
end
Run Code Online (Sandbox Code Playgroud)
关于为什么这不起作用的任何想法?关于如何以不同的方式工作的任何想法?我知道我可以摆脱default_scope,但我想知道是否还有另一种方法可以做到这一点.
class CreateCrews < ActiveRecord::Migration
def self.up
create_table :crews do |t|
t.string :title
t.text :description
t.boolean :adult
t.boolean :private
t.integer :gender_id
t.boolean :approved, :default => false
t.timestamps
end
end
def self.down
drop_table :crews
end
end
class Crew < ActiveRecord::Base
has_many :users, :through => :crew_users
belongs_to :user
default_scope where(:approved => true)
end
Run Code Online (Sandbox Code Playgroud)
当我进入控制台并创建新记录时,"已批准"属性设置为true,为什么?
如何将其自动设置为默认值(false),如我的迁移文件中所示?
wojciech@vostro:~/work/ze$ rails console
Loading development environment (Rails 3.0.0)
ruby-1.9.2-p0 > c = Crew.new
=> #<Crew id: nil, title: nil, description: nil, adult: nil, private: nil, gender_id: nil, approved: …
在Rails 3.1 RC6上,给出
class Animal < ActiveRecord::Base
default_scope where(legs: 4)
end
Run Code Online (Sandbox Code Playgroud)
以下内容无法按预期工作:
class Man < Animal
default_scope unscoped.where(legs: 2)
end
Run Code Online (Sandbox Code Playgroud)
生成的SQL语句如下所示:
SELECT * FROM animals WHERE legs = 4 AND legs = 2
Run Code Online (Sandbox Code Playgroud)
如何完全覆盖父类的默认范围?
我也尝试了以下所有工作:
default_scope{ unscoped.where legs: 2 }
default_scope with_exclusive_scope{ legs: 2 }
Run Code Online (Sandbox Code Playgroud) default-scope ×10
activerecord ×3
scope ×2
activeadmin ×1
migration ×1
models ×1
rspec ×1
ruby ×1
sti ×1
testing ×1