我有一个有很多孩子的简单父对象.我正在试图弄清楚如何使用命名范围来带回具有特定数量的孩子的父母.
这可能吗?
class Foo < ActiveRecord::Base
has_many :bars
named_scope :with_no_bars, ... # count of bars == 0
named_scope :with_one_bar, ... # count of bars == 1
named_scope :with_more_than_one_bar, ... # count of bars > 1
end
class Bar < ActiveRecord::Base
belongs_to :foo
end
Run Code Online (Sandbox Code Playgroud)
我希望能做类似的事情 Foo.with_one_bar
我可以在父类上编写类似这样的方法,但我宁愿拥有命名范围的强大功能
我有一个问题和解决方案模型.问题有很多解决方案,解决方案属于问题.
我需要得到最近解决的问题,这意味着,获得最后的X解决方案并解决它的问题.我很确定有一种方法可以用named_scopes做到这一点,但我无法弄明白.
任何帮助真的很感激:-)
谢谢,
尼古拉斯·霍克一世
我可以返回一个对象集合,只有一个(:limit => 1)但是有没有办法只返回.first()对象,就像不在集合中一样?
named_scope :profile, :conditions => {:association => 'owner', :resource_type => 'Profile'}, :limit => 1 # => collection of 1 profile but I want the profile only NOT in a collection or array
Run Code Online (Sandbox Code Playgroud)
解决方法只是将.first()应用于结果,但我只想清理代码并使其不易出错.
是否有相当于AR的命名范围?命名范围基本上是过滤器,可以包装在方法中,然后链接.
以下是http://archives.ryandaigle.com/articles/2008/8/20/named-scope-it-s-not-just-for-conditions-ya-know的示例:
class Article < ActiveRecord::Base
# Get all articles that have been published
named_scope :published, :conditions => ['published = ?', true]
# Get all articles that were created recently
named_scope :recent, lambda { { :conditions => ['created_at >= ?', 1.week.ago] } }
end
# Get all recently created articles that have been published
Article.published.recent
Run Code Online (Sandbox Code Playgroud)
以下是使用Django ORM的示例:http://furrybrains.com/2009/06/22/named-scopes-for-django/
我想在站点用户编辑/创建页面中进行语言选择下拉列表.
为此,我当然将网站翻译成多种语言.使用I18n.available_languages,我可以得到一个区域代码数组,就像这样
development environment (Rails 2.3.4)
> I18n.available_locales
=> [:en, :da]
Run Code Online (Sandbox Code Playgroud)
此外,我创建了一个语言模型并将其与用户相关联:
# app/models/language.rb
class Language < ActiveRecord::Base
has_many :users
end
# app/models/user.rb
class User < ActiveRecord::Base
belongs_to :language
end
# db/schema.rb
create_table "languages", :force => true do |t|
t.string "name"
t.string "code"
end
create_table "users", :force => true do |t|
t.integer "language_id"
end
Run Code Online (Sandbox Code Playgroud)
然后语言表包含本地语言中的语言环境代码和语言名称,如下所示:
| id | name | code |
------------------------------------
| 28 | Dansk | da |
| 29 | Nederlands | nl |
| 30 | …Run Code Online (Sandbox Code Playgroud) 我尝试以下列方式定义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.
谢谢!
来自Agile Web Development With Rails一书
class Order < ActiveRecord::Base
named_scope :last_n_days, lambda { |days| {:conditions =>
['updated < ?' , days] } }
named_scope :checks, :conditions => {:pay_type => :check}
end
Run Code Online (Sandbox Code Playgroud)
该声明
orders = Orders.checks.last_n_days(7)
Run Code Online (Sandbox Code Playgroud)
只会对数据库进行一次查询.
rails如何实现这一目标?我是Ruby的新手,我想知道是否有一个允许这种情况发生的特殊构造.
为了能够链接这样的方法,named_scope生成的函数必须返回自己或者可以进一步调整范围的对象.但Ruby如何知道它是最后一个函数调用,它现在应该查询数据库?
我问这个是因为上面的语句实际上是查询数据库而不仅仅是返回链接产生的SQL语句.
我有2个简单的命名范围定义如下:
class Numbers < ActiveRecord::Base
named_scope :even, :conditions => {:title => ['2','4','6']}
named_scope :odd, :conditions => {:title => ['1','3','5']}
end
Run Code Online (Sandbox Code Playgroud)
如果我打电话给Numbers.even我回来2,4,6这是正确的,如果我打电话给Numbers.odd我回来1,3,5这是正确的
当我将它们链接在一起时:Numbers.even.odd我得到1,3,5因为这是我引用的最后一个范围.所以,如果我说Numbers.odd.even,我实际上会得到2,4,6.
当我将它们链接在一起时,我希望得到1,2,3,4,5,6.我尝试的另一种方法是:
named_scope :even, :conditions => ["title IN (?)", ['2', '4','6']]
named_scope :odd, :conditions => ["title IN (?)", ['1', '3','5']]
Run Code Online (Sandbox Code Playgroud)
但是当我将它们链接在一起时,我得不到任何结果,因为它创建的查询看起来像这样:
SELECT * FROM `numbers`
WHERE ((title IN ('1','3','5')) AND (title IN ('2','4',6')))
Run Code Online (Sandbox Code Playgroud)
'AND'子句应该改为OR,但我不知道如何强迫它.这可能是ActiveRecord的一个问题吗?
亲爱的,我有一个Student,我已经指定一些模式name_scope在里面,例如from_program,from_year,from_school,has_status,from_course,等...
无论如何,我可以named_scope在运行时根据某些标准动态地将不同的链接在一起吗?
例如,如果访问数据的用户是从金融,我想能够链from_school和has_status仅在一起.如果用户是讲师,我希望能够给链from_course,from_school在一起,等等...
我应该用named_scope吗?或者我应该回到指定条件的旧方法?
提前感谢您的建议!=)顺便说一句,我正在使用rails 2.3
有没有办法可以将以下代码中的to_be_approved方法转换为使用其他两个范围的范围?
scope :reports_to, lambda { |manager|
joins(" JOIN admin_users request_user on requests.admin_user_id = request_user.id and request_user.manager_id = #{manager.id} ") }
scope :pending, joins(:admin_request_status).where('admin_request_statuses.name = ?','Pending Approval')
def self.to_be_approved_by( manager )
reports_to(manager).pending
end
Run Code Online (Sandbox Code Playgroud)
我也想摆脱reports_to范围内的嵌入式sql,但这是一个完全不同的问题:)