Make sure that if the specific active recording object is in a particular scope,

Currently, when I save, I try to check if the record falls into a specific area. This "scope" really is just some of the stored arguments for calling .where. In addition, with this β€œscope” I only check the values ​​of the object, and not ever, as it relates to other objects in the database, so the database query will always be killed if that makes sense.

I could only come up with a solution below.

begin result = self.class.where(scope).find(self.id) rescue result = false end 

The problem is that I have to query the database, even if I already have a record, and I have to run it not only before saving, but also after saving, to check the values ​​that it was and the values ​​that will be after saving because there is no way to query the database for the updated version if it has not been saved.

There may be some of these checks, so I would like to avoid having to do this twice, and also query the database many times, even if in the end I was just looking for something by id.

The only other solution I could think of is to have a method that somehow converts the where call to proc, which returns a boolean when the object is passed. The only problem with this is that the translation will somehow how to work with an active recording adapter, which is like an entire project on its own. So does anyone know some way to do this or a stone that will help?

PS I get the "region" from the cache, so I can not save it as proc, because you can not put procs in the cache using Rails.

+7
source share
2 answers

you can improve your first decision a bit first

 result = self.class.where(scope).exists?(self.id) 

if you don't want to check the database, why don't you just check if your object attributes have scope values? if your volume

 class.where(:attr1 => value1, :attr2 => value2, :attr3 => value3) 

then you can do

 result = self.attr1 == value1 and self.attr2 == value2 and self.attr3 == value3 
+5
source

If your scope is simple, you probably want to avoid code duplication. My solution allows you to call model.active? to find out if the instance of the scope belongs, and Model.active to find all records matching the scope. model.active? does not contain database queries.

consider adding this to config/initializers/scope_and_method.rb :

 require 'active_record/named_scope' module ActiveRecord::NamedScope::ClassMethods def scope_and_method field, *values field = field.to_sym values.each do |value| named_scope value.to_sym, :conditions => {field => value} define_method "#{value}?" do send(field.to_sym) == value end end end end 

Using:

 scope_and_method :state, 'active', 'inactive' 

It works as if:

 named_scope :active, :conditions => {:state => 'active'} named_scope :inactive, :conditions => {:state => 'inactive'} def active? state == 'active' end def inactive? state == 'inactive' end 

This is a solution for Rails 2.3. This requires very little customization for Rails 3 and 4. ( named_scope scope ) I'll check back soon.

+3
source

All Articles