名为范围之间的分享方法 -- ruby-on-rails 领域 和 activerecord 领域 相关 的问题

Share methods between named scopes


简体版||繁體版
4
vote

问题

中文

我有一堆命名范围,并在其中一个人中有一种方法,我想在另一个命名范围之间分享。我使用define_method和lambda种了一切完成的。但是,还有一些重复的代码,我想知道有更好的方法吗?

这是我所拥有的简化示例。假设我有一个项目表,每个项目都有很多用户。

在用户模型中,我有...
  filter_by_name = lambda { |name| detect {|user| user.name == name} }  named_scope :active, :conditions => {:active => true} do   define_method :filter_by_name, filter_by_name end  named_scope :inactive, :conditions => {:active => false} do   define_method :filter_by_name, filter_by_name end  named_scope :have_logged_in, :conditions => {:logged_in => true} do   define_method :filter_by_name, filter_by_name end   

然后我会使用它...

  active_users = Project.find(1).users.active  some_users = active_users.filter_by_name ["Pete", "Alan"] other_users = active_users.filter_by_name "Rob"  logged_in_users = Project.find(1).users.logged_in  more_users = logged_in_users.filter_by_name "John"   
英文原文

I have a bunch of named scopes and have a method within one of them that I would like to share between the other named scopes. I've sort of accomplished this by using define_method and a lambda. However, there is still some repeated code and I'm wondering is there a better approach?

Here's a simplified example of what I've got. Assume I have a table of projects and each project has many users.

Within the User model I have...

filter_by_name = lambda { |name| detect {|user| user.name == name} }  named_scope :active, :conditions => {:active => true} do   define_method :filter_by_name, filter_by_name end  named_scope :inactive, :conditions => {:active => false} do   define_method :filter_by_name, filter_by_name end  named_scope :have_logged_in, :conditions => {:logged_in => true} do   define_method :filter_by_name, filter_by_name end 

Then I would use it like...

active_users = Project.find(1).users.active  some_users = active_users.filter_by_name ["Pete", "Alan"] other_users = active_users.filter_by_name "Rob"  logged_in_users = Project.find(1).users.logged_in  more_users = logged_in_users.filter_by_name "John" 
     

回答列表

2
 
vote
vote
最佳答案
 

这是一个完全不同的解决方案,可能更多的是质疑问题所要求的。

named_scope需要一个可能是任何proc的块。因此,如果创建一个定义过滤器_by_name方法的lambda / proc,则可以将其作为named_scope的最后一个参数传递。

          for(int r=0;r<table.getRowCount();r++) {             if(!table.getValueAt(r, 2).equals(table.getValueAt(r, 3))) {                 for(int c=0;c<table.getColumnCount();c++) {                     table.setValueAt("<html><b>" + table.getValueAt(r, c) + "</b></html>", r, c);                 }             }         } 6  

这将做你正在寻找的。如果您仍然认为它过于重复,可以将其与MRJake2的解决方案中的技术相结合,以一次定义许多命名范围。这样的东西:

          for(int r=0;r<table.getRowCount();r++) {             if(!table.getValueAt(r, 2).equals(table.getValueAt(r, 3))) {                 for(int c=0;c<table.getColumnCount();c++) {                     table.setValueAt("<html><b>" + table.getValueAt(r, c) + "</b></html>", r, c);                 }             }         } 7  
 

Here's an entirely different solution that is probably more in spirit with what the question was asking for.

named_scope takes a block, which could be any Proc. So if you create a lambda/Proc which defines the filter_by_name method, you can pass it as the last argument to a named_scope.

filter_by_name = lambda { |name| detect {|user| user.name == name} }  add_filter_by_name = lambda { define_method :filter_by_name, filter_by_name }  named_scope(:active, :conditions => {:active => true}, &add_filter_by_name)  named_scope(:inactive, :conditions => {:active => false}, &add_filter_by_name)  named_scope(:have_logged_in, :conditions => {:logged_in => true}, &add_filter_by_name) 

This will do what you're looking for. If you still think it's too repetitive, you can combine it with the techniques in mrjake2's solution to define many named scopes at once. Something like this:

method_params = {   :active => { :active => true },   :inactive => { :active => false },   :have_logged_in => { :logged_in => true } }  filter_by_name = lambda { |name| detect {|user| user.name == name} }  add_filter_by_name = lambda { define_method :filter_by_name, filter_by_name }  method_params.keys.each do |method_name|   send(:named_scope method_name, :conditions => method_params[method_name],      &add_filter_by_name) end 
 
 
 
 
2
 
vote

可以链接命名的范围,所以你对自己的自我变得更加困难。

在用户模型中定义时下面将为您提供所需的内容:

  class User < ActiveRecord::Base   ...   named_scope :filter_by_name, lambda { |name|       {:conditions => { :name => name}  }   }    named_scope :active, :conditions => {:active => true}     named_scope :inactive, :conditions => {:active => false}     named_scope :have_logged_in, :conditions => {:logged_in => true}  end   

然后以下代码段将工作:

  active_users = Project.find(1).users.active  some_users = active_users.filter_by_name( ["Pete", "Alan"] other_users = active_users.filter_by_name "Rob"  logged_in_users = Project.find(1).users.have_logged_in  more_users = logged_in_users.filter_by_name "John"   

我看到你正在使用 detect ,可能避免多余的击中DB。但是您的示例不会正确使用它。检测只返回块返回true的列表中的第一个元素。在上面的示例中, some_users 只会是一个记录,第一用户名为"Pete" 或"Alan" 。如果您希望获得名为"Pete" 或"Alan" 的所有用户,那么您想要 <代码> select 。如果你想要 select 那么你最好使用命名范围。

命名范围当评估时,返回一个特殊对象,该对象包含构建SQL语句以生成结果所需的组件,链接其他命名范围仍未执行该语句。直到您尝试访问结果集的方法,例如调用每个或地图。

 

Named scopes can be chained, so you're making this harder on your self than you need to.

The following when defined in the user model will get you what you want:

class User < ActiveRecord::Base   ...   named_scope :filter_by_name, lambda { |name|       {:conditions => { :name => name}  }   }    named_scope :active, :conditions => {:active => true}     named_scope :inactive, :conditions => {:active => false}     named_scope :have_logged_in, :conditions => {:logged_in => true}  end 

Then the following snippets will work:

active_users = Project.find(1).users.active  some_users = active_users.filter_by_name( ["Pete", "Alan"] other_users = active_users.filter_by_name "Rob"  logged_in_users = Project.find(1).users.have_logged_in  more_users = logged_in_users.filter_by_name "John" 

I see that you're using detect, probably to avoid excess hits to the DB. But your examples don't use it properly. Detect only returns the first element in a list that the block returns true for. In the above example, some_users will only be a single record, the first user that is named either "Pete" or "Alan". If you're looking to get all users named "Pete" or "Alan" then you want select. And if you want select then you're better off using a named scope.

Named scopes when evaluated return a special object that contains the components necessary to build the SQL statement to generate the results, chaining other named scopes still doesn't execute the statement. Not until you try to access methods on the result set, such as calling each or map.

 
 
   
   
1
 
vote

我可能会使用一些元标记:

  method_params = {   :active => { :active => true },   :inactive => { :active => false },   :have_logged_in => { :logged_in => true } }  method_params.keys.each do |method_name|   send :named_scope method_name, :conditions => method_params[method_name] do     define_method :filter_by_name, filter_by_name   end end   

这样如果您想在将来添加更多查找器,您可以将方法名称和条件添加到方法_Param哈希。

 

I would probably use a bit of metaprogramming:

method_params = {   :active => { :active => true },   :inactive => { :active => false },   :have_logged_in => { :logged_in => true } }  method_params.keys.each do |method_name|   send :named_scope method_name, :conditions => method_params[method_name] do     define_method :filter_by_name, filter_by_name   end end 

This way if you wanted to add more finders in the future, you could just add the method name and conditions to the methods_param hash.

 
 
   
   
0
 
vote

您还可以使用第二个命名范围来执行此操作。

  named_scope :active, :conditions => {:active => true} named_scope :inactive, :conditions => {:active => false} named_scope :have_logged_in, :conditions => {:logged_in => true}  named_scope :filter_by_name, lambda {|name| :conditions => ["first_name = ? OR last_name = ?", name, name]}   

然后您可以执行 @project.users.active.filter_by_name('Francis')

如果您真的需要用枚举#检测完成此操作,我会在模块中定义筛选器_by_name方法,然后可以扩展命名范围:

  with_options(:extend => FilterUsersByName) do |fubn|   fubn.named_scope :active, :conditions => {:active => true}   fubn.named_scope :inactive, :conditions => {:active => false}   fubn.named_scope :have_logged_in, :conditions => {:logged_in => true} end  module FilterUsersByName   def filter_by_name(name)     detect {|user| user.name == name}   end end   

这将筛选器_by_name方法添加到所有三个名为scopes返回的类中。

 

You can also do this with a second named scope.

named_scope :active, :conditions => {:active => true} named_scope :inactive, :conditions => {:active => false} named_scope :have_logged_in, :conditions => {:logged_in => true}  named_scope :filter_by_name, lambda {|name| :conditions => ["first_name = ? OR last_name = ?", name, name]} 

Then you can do @project.users.active.filter_by_name('Francis').

If you really need to do this with Enumerable#detect, I would define the filter_by_name method in a module which can then extend the named scopes:

with_options(:extend => FilterUsersByName) do |fubn|   fubn.named_scope :active, :conditions => {:active => true}   fubn.named_scope :inactive, :conditions => {:active => false}   fubn.named_scope :have_logged_in, :conditions => {:logged_in => true} end  module FilterUsersByName   def filter_by_name(name)     detect {|user| user.name == name}   end end 

This adds the filter_by_name method to the class returned by all three named scopes.

 
 

相关问题

1  如何在轨道上连接两个ActiveRecord查询  ( How to concatenate two activerecord queries in rails ) 
我有一个简单的应用程序,具有用户模型,角色模型,带收件人的消息模型。 用户通过角色具有许多邮件 并且一个角色通过收件人和用户通过收件人的消息也有许多消息。 收件人模型具有user_id,core_id和message_id 现在我想在一个查询中显示用户的所有邮件,包括他的角色消息和他的个人信息。如何完成此操作。 ...

1  如何构建Rails链接,以便单击它将更新ActiveRecord属性  ( How to structure rails link so that clicking it will update an activerecord attr ) 
我有两个型号,属性模型和应用模型。应用程序has_many属性,属性属于_to应用程序。因此,属性模型具有"application_id" 字段,它表示与属性关联的应用程序。 我想在property show page上显示一份所有可能的应用程序的列表,其中包含应用程序的链接,如果单击,将简单地将属性模型中的appl...

1  使用ActiveRecord找到5个嵌套表的结果  ( Use activerecord to find result of 5 nested tables ) 
我有一个用户型号(:姓名,:密码,电子邮件)和事件模型(:name,:等)和兴趣模型(:name) 然后我创建了两个加入表 - &gt;用户记录和活动情绪;每个都不包含主键,并且仅包括user_id / exing_id和event_id / exing_id。 我正在尝试使用astiveRecord来查询列出兴趣事...

1  我可以在2个不同的表字段中汇总值,并通过Rails / Active Record排序该值吗?  ( Can i sum values in 2 different table fields and sort on that value via rails ) 
我有逾期和捐赠模型。我想通过总计+捐款列出成员。这是活动的记录是否可以专门,或者我必须在应用程序中进行一些添加和排序代码? db是postgres ...

0  Rails迁移以生成日历表  ( Rails migration to generate a calendar table ) 
如何在Rails迁移上编写Ruby以生成日历表,其中包含2010年1月至12月2099年1月之间的所有日期? ...

6  Rails ActiveRecord Serialize方法在测试环境中不起作用  ( Rails activerecord serialize method doesnt work in test environment ) 
我遇到了activeRecord serialize 方法我的测试。 它只是给了我纯的字符串而不是我的数据数组。 示例: User > ActiveRecord::Base serialize :roles, Array end 控制台: u = User.new u.roles = ["adm...

8  Rails:显示@CARS作为逗号分隔的列表  ( Rails display cars as a comma separated list ) 
基于此查询: @cars = Car.where("manufacturer_id IN ?", @mfts.select("id")).limit(30).select("id") 如何在这样的视图中显示汽车的ID(或者我需要重写我的查询)? 3,2,5,12,15,24,34,63,64,65,66...

0  轨道3的陈旧Activerecord协会的问题  ( Problem with stale activerecord association in rails 3 ) 
我有三种型号:网站,订阅,计划: 网站 E.g value = test, _dff = 323, 0 订阅 E.g value = test, _dff = 323, 1 计划 E.g value = test, _dff = 323, 2 在我的订阅范围控制器中,我首先加...

0  在Rails 3中加入一对多协会与许多多对多协会  ( Joining a one to many association with a many to many association in rails 3 ) 
我在用户类和表类之间有多对多关联。此外,我在用户和表格之间有一对多关联(一个用户最终拥有该表)。我正在尝试访问用户可以访问的所有表(基本上加入两个关联)。 另外,使用named_scope(现在的范围)是很好的。 这是我到目前为止的内容: class User < ActiveRecord::Base act...

0  获取用户的ID,在数据库中搜索他/她的名字  ( Getting the id of a user after searching for his her name in the database ) 
所以当用户完成测验时,他/她填写了他/她的姓名和电子邮件。在提交时,我需要在用户DB中创建用户,以及在相关答案DB中存储个人答案。显然,对于Contact_ID字段,我需要输入联系人的ID:name =&gt; params [:name]。当我on tack时。在声明结束时我得到"无方法错误ID" 。当我在视图中时...

0  @ user.visit_count =>未定义的方法  ( User visit count undefined method ) 
我正在做我想的是非常简单的东西 - 找到一个用户并递增整数。 recording.wav6 我收到以下错误: recording.wav7 这似乎是一个轨道3件事 - 我在哪里出错了? ...

0  mysql查询哪里......或...快捷方式  ( Mysql query where or shortcut ) 
是否有用于编写以下MySQL查询的快捷方式?我正在寻找一种压缩的速记 SELECT * FROM `listings` where `bedroom` = 1 OR `bedroom` = 2 因为我想更容易动态构建PHP中的MySQL查询。类似于 WHERE bedroom = 1, 2 ,因为我从php...

1  yii,生成Unque ID的每个TR元素的CGridView  ( Yii generate unquie ids one each tr element of cgridview ) 
我有一个cdbactiverecord设置,我有一个cgridview类设置为小部件的实例。 基本上我的结局游戏是我需要一个表,但每行都包含与活动记录关联的行的主键。 如: package be.gillescoeman.scubajournal; // import android.app.Fragm...

0  在项目中难以使用ActiveMerchant,这些项目不使用ActiveRecord作为它的ORM?  ( Difficult to use activemerchant in a project that does not use activerecord as i ) 
ActiveMerchant似乎被同意烘烤。 我基于购买()方法返回ActiveRecord :: Billing ::响应对象: 是正确的,如果是这样,这是否意味着难以在使用不同的Ruby ORM(续集/ DataApper)的项目中使用ActiveMerchant? ...

1  使用ROR使用e-a-v的传统表  ( Using ror with a legacy table that uses e a v ) 
我需要连接到传统数据库并从使用实体属性值模型的表中提取数据的子集来存储联系人的信息。该表看起来如下: SubscriberID FieldID数据 1 2杰克 1 3个麻雀 2 2丹 2 3史密斯 其中 fieldid 是一个外键到 fields 表格,列出给定客户可以拥有的自定义字段(例如,名字,姓氏,电话)。...

2  我应该扩展这个课吗? (PHP)  ( Should i be extending this class php ) 
我在php中创建一个orm,我有一个类'orm',基本上创建了与数据库表对应的对象(我的目标是与activerecord模式类似于/相同的功能。)ORM它本身扩展了"数据库" ,它设置了数据库连接。 所以,我可以拨打电话: $c = new Customer(); $c->name = 'John Smith'; ...

1  HOWTO处理ActiveRecord 3.0.4和DB_Chereaner的嵌套事务  ( Howto handle nested transaction with activerecord 3 0 4 and db cleaner ) 
我们正在使用db_cleaner使用Clean Method :transaction 在Rails 3.0.4应用程序(我们无法升级)mysql 5.x db。我们无法使用 :truncation ,导致我们松散的种子数据。 现在我们面临以下问题。 ActiveRecord自动生成一个事务,当例如 :create...

2  尝试访问Join Table Rails中的属性  ( Trying to access attribute in join table rails ) 
好的我认为我有两个需要修复的问题 我有以下表格: Student , Register Register Register 和一个连接表,它显示1 register有许多学生的记录,称为"regisers_students" ,看起来像这样:. 我必须通过 rails g migration CreateS...

0  如何获得多功能者模型,只有1个连接查询在yii2中?  ( How to get multi activerecord model with only 1 join query in yii2 ) 
例如: 查询 SELECT book.*,author.* FROM book INNER JOIN author ON author.id = book.author_id WHERE book.id=1 获取模型 $modelBook = Book::find()->innerJoin...

0  Rails 3 - 拥有和“跟踪”相同的对象类型使用has_many和has_many作为:可跟踪(多态)  ( Rails 3 owning and tracking the same object type using has many and has many ) 
在我的项目中,我需要 User 能够"创建/拥有" 它自己的对象和"跟踪" (或"关注" )由其他用户创建的对象。这是我的方法: class User < ActiveRecord::Base has_many :widgets has_many :gadgets has_many :nuggets ...

1  在Rails中,您如何将这两个不同的HAS_MANYS合并为一个?  ( In rails how would you merge these two different has manys into one ) 
让我们说我们有一个用户。 用户通过账户_many文档如此... class User < ActiveRecord::Base belongs_to :account has_many :documents, :through => :account, :order => "created_at DES...

1  有条件地覆盖Activerecord的删除机制是什么是最好的方法?  ( Whats the best way to conditionally override activerecords deletion mechanism ) 
我试图劫持rails的删除机制,使其对某一组模型不同。 两个 ActiveRecord::Base#delete 和 #destroy #destroy 引线回到 ActiveRecord::Relation#delete_all ,因此覆盖此方法会有意义。 我已经尝试过... class MyModel...

3  自定义ActiveRecord查找器调用命名范围?  ( Custom activerecord finder invoking named scopes ) 
我有一个定义的定制查找器: class ContainerGateIn << ActiveRecord::Base ... def self.search(text) result = if text text.split(' ').inject(self) do |result, c...

2  Ruby在Rails上的自动保存选项  ( Autosave options in ruby on rails ) 
有没有办法在轨道中关闭自动保存?我不希望修改关联以自动保存到数据库,直到我调用保存在父对象上。 some_parent.some_children << child #should not save, just adds to the association! some_parent.save #now pa...

240  Rails Rake任务是否可以访问ActiveRecord型号?  ( Do rails rake tasks provide access to activerecord models ) 
我正在尝试创建一个自定义rake任务,但似乎我没有访问我的模型。我认为这是含有rails任务的东西。 我在lib / tasks / test.rake中有以下代码: namespace :test do task :new_task do puts Parent.all.inspect end ...

相关问题

1  如何在轨道上连接两个ActiveRecord查询 
1  如何构建Rails链接,以便单击它将更新ActiveRecord属性 
1  使用ActiveRecord找到5个嵌套表的结果 
1  我可以在2个不同的表字段中汇总值,并通过Rails / Active Record排序该值吗? 
0  Rails迁移以生成日历表 
6  Rails ActiveRecord Serialize方法在测试环境中不起作用 
8  Rails:显示@CARS作为逗号分隔的列表 
0  轨道3的陈旧Activerecord协会的问题 
0  在Rails 3中加入一对多协会与许多多对多协会 
0  获取用户的ID,在数据库中搜索他/她的名字 
0  @ user.visit_count =>未定义的方法 
0  mysql查询哪里......或...快捷方式 
1  yii,生成Unque ID的每个TR元素的CGridView 
0  在项目中难以使用ActiveMerchant,这些项目不使用ActiveRecord作为它的ORM? 
1  使用ROR使用e-a-v的传统表 
2  我应该扩展这个课吗? (PHP) 
1  HOWTO处理ActiveRecord 3.0.4和DB_Chereaner的嵌套事务 
2  尝试访问Join Table Rails中的属性 
0  如何获得多功能者模型,只有1个连接查询在yii2中? 
0  Rails 3 - 拥有和“跟踪”相同的对象类型使用has_many和has_many作为:可跟踪(多态) 
1  在Rails中,您如何将这两个不同的HAS_MANYS合并为一个? 
1  有条件地覆盖Activerecord的删除机制是什么是最好的方法? 
3  自定义ActiveRecord查找器调用命名范围? 
2  Ruby在Rails上的自动保存选项 
240  Rails Rake任务是否可以访问ActiveRecord型号? 



© 2021 it.wenda123.org All Rights Reserved. 问答之家 版权所有