How to Use a Named Scope in My Model Against an Array of Items

How can I use a named scope in my model against an array of items?

If you pass an array as the value, ActiveRecord is smart enough to compare for inclusion in the array. For example,

Book.where(:author_id => [1, 7, 42])

produces a SQL query with a WHERE clause similar to:

WHERE "author_id" IN (1, 7, 42)

You can take advantage of this in a scope the same way you would set normal conditions:

class Book < ....
# Rails 3
scope :by_author, lambda { |author_id| where(:author_id => author_id) }

# Rails 2
named_scope :by_author, lambda { |author_id
{ :conditions => {:author_id => author_id} }
}
end

Then you can pass a single ID or an array of IDs to by_author and it will just work:

Book.by_author([1,7,42])

Rails scope with array as argument Rails 4

Since a scope is just syntactic sugar for a Class method anyways, I would recommend just creating it as a class method and the whole thing becomes much easier/cleaner:

class Member < ActiveRecord::Base

self.find_by_full_name(array_of_names)
members = []

array_of_names.each do |name|
split_names = name.split(' ')
members.push(Member.find_by_first_name_and_last_name(split_names.first, split_names.last))
end

members.compact
end

end


UPDATE

And then you could even extend the capabilities of it easily (one additional line) if you wanted it to be able to accept either a single name or an array of names:

class Member < ActiveRecord::Base

self.find_by_full_name(names)
members = []
names = [names] if names.is_a?(String)

names.each do |name|
split_names = name.split(' ')
members.push(Member.find_by_first_name_and_last_name(split_names.first, split_names.last))
end

members.compact
end

end


NOTE

Not sure if you're familiar with .compact but that will accomplish the "if it exists" portion of your question. The Member.find_by... will push a nil value onto members if there isn't a match, and then .compact will remove the nil values from members.

How can I make named_scope in Rails return one value instead of an array?

As Damien mentions, using a custom scope just to look up by ID isn't advisable. But to answer your question:

Finding records with named_scope will always return an ActiveRecord::NamedScope::Scope object, which behaves like an array. If there is just a single record returned by your query, you can use the first method to get the ActiveRecord object directly, like this:

event = Event.from_id(id).first
event.name # will work as you expect

Given an array of ActiveRecord objects, can I easily collect their relationships through a method call?

You could extend the array returned by Site.find.

class Site
def find(*args)
result = super
result.extend LanguageAggregator if Array === result
result
end
end

module LanguageAggregator
def languages
Language.find(:all, :conditions => [ 'id in (?)', self.collect { |site| site.id } ])
end
end

How to update item in Model array in different scopes, and have changes reflect everywhere?

For you problem I'd like to resolve this issue by create a factory which will be sharable in all controllers

app.service('sharableService',[ function(){
this.sharableData = {};
//getter
this.getData = function(){
return this.sharableData;
}
//setter
this.setData = function(value){
this.sharableData = value;
}
}]);

OR

Factory

app.factory('sharableService',[ function(){
var sharableData = {};
//getter
var getData = function(){
return sharableData;
}
//setter
var setData = function(value){
sharableData = value;
}
//method are exposed.
return {
getData: getData,
setData: setData
}
}]);

This sharable service can be use full to share data between controllers.

How to call an array of scopes on an ActiveRecord object?

just use inject:

scopes.inject(Article){ |ar,scope| ar.send(scope) }


Related Topics



Leave a reply



Submit