How do you call "contains?" on a MongoMapper Array in Rails 3? - ruby-on-rails

I want to know how to check if an array element exists inside of a MongoMapper Array. This question is the closest I could find, but it addresses queries rather than simply using a document you already have.
My User model contains the line
key :roles, Array
The 'roles' array contains strings such as 'admin' or 'user.' For authorization, I need to call something like the following method on an instance of User:
if user.roles.contains?('admin')
# Do administrative stuff.
end
But when I try to call 'contains?' Ruby complains that there is no such method:
NoMethodError (undefined method `contains?' for #<Array:0x007fc845cd8948>):
app/models/ability.rb:11:in `initialize'
app/controllers/settings_controller.rb:5:in `index'
If there's no way to do this, then how do I convert the Array into a Ruby array to call 'contains?'? Calling to_a isn't doing it:
if user.roles.to_a.contains?('admin') # etc...
I'm using Rails 3.2.13, Ruby-1.9.3-p392, and MongoMapper 0.12.0 on Mountain Lion.

the function you are looking for is include?, so the expression would be: user.roles.include?('admin')
However since you mentioned mongomapper, if you were preforming a query on the roles array you would do the fallowing:
User.where( :roles => 'admin' )
You can also search an array with an array
User.where( :roles.in => ['admin'] )
for a query with admin or user you can do:
User.where( :$or => [{:roles => 'admin'},{:roles => 'user'}] )
and you can do and just the same:
User.where( :$and => [{:roles => 'admin'},{:roles => 'user'}] )

Related

to_json wrapping a single object in array?

In my API, I am converting an ActiveRecord object into json via:
user.to_json :methods => :new_messages
Using irb, when I execute this statement, I get:
{someAttr: someValue, ....}
which is perfect. This is a single object so it's not wrapped in an array. Now when I run this in sinatra app like this:
get '/api/users/:fb_id' do |fb_id|
user = User.where :fb_id => fb_id
user.to_json :methods => :new_cookies
end
It wraps it in an array!!! Like this:
[{someAttr: someValue, ....}]
How can I fix this, and more importantly, why?!?
Simply using Hash.[]
Hash[{a: :b}]
# => {:a=>:b}
and more importantly, why?!?
Which ORM are you using in the second example? If it's ActiveRecord, then User.where :fb_id => fb_id returns ActiveRecord::Relation object which wraps into an array when you call .to_json. It can be fixed like so
get '/api/users/:fb_id' do |fb_id|
user = User.find_by_fb_id(fb_id)
user.to_json :methods => :new_cookies
end
replace this line:
user = User.where :fb_id => fb_id
with this line:
user = User.find_by_fb_id fb_id

Mongoid: Added Hash to Model but can't write to it

I've got a model, Entity.
class Entity
include Mongoid::Document
field :x
field :y
field :z, type => Hash, :default => {} # new field
end
I added a new field to it, a hash. When I try to use it, I get an error. My code is:
e = Entity.first
if e.z["a"] # if there is a key of this in it?
e.z["a"] = e.z["a"] + 1
else
e.z["a"] = 1
end
But, this error with an undefined method get for hash. If I try to create an initializer for it, to set the values in an existing document, it errors with the same error. What am I doing wrong?
Initializer looks like:
e = Entity.first
e.write_attribute(:z, {})
Thanks
Sorted it.
It seems the answer is to set in Mongoid 1.9.5 the hash to:
field :hash_field, :type => Hash, :default => Hash.new
and it can access and initialize it. Not quite understanding why, but happy to have the answer !

Metaprogramming in Ruby On Rails

I have an array of strings: ["users", "torrents", "comments"]
these strings are the names of my bd tables.
how can I in .each loop connect to these tables and select|insert some data?
Avoid using eval
here is a simple solution using constantize
note: constantize will not allow arbitrary code to evaluated, it will just try to fetch a ruby constant, namely a Class
["users", "torrents", "comments"].each do |table_name|
# "users" => "User"
# or more complex
# "some_models" => "SomeModel"
#
class_name = table_name.singularize.camelize
# "User" => User
model_class = class_name.constantize
# do something with it
model_class.create!(:value => 12345)
end

Rails - ActiveResource returning hash instead of an object

I've got the following code
u = Client.get(:show_by_username, :username => username.downcase)
When a valid user is returned, they seem to be getting returned as a hash instead of an object that I can call methods on
e.g. I have to access values like
u['id']
instead of
u.id
How can I get it to return it as an object?
Thanks
As described in the docs for the ActiveResource 'get' method, it does not convert them into ActiveResource::Base instances. As it says, you need to use the find method instead:
u = Client.find(:all, :from => :show_by_username, :params => { :username => username.downcase })

Rails 3, Active Record query returns ActiveRecord::Relation object, instead of objects

I feel like this is a simple problem I'm having due to my misunderstanding of the new ActiveRecord query interface, but take this example:
>> Category.first.recipes
=> [ ... ] # array of recipes
However:
>> Category.where(:id => 1).recipes
=> NoMethodError: undefined method `recipes' for #<ActiveRecord::Relation:0x000001033dc9e0>
What's going on here? why does my where method return an ActiveRecord::Relation object? how can I retrieve the objects from the query here?
This is actually intentional.
Category.where(:id => 1)
# Is Equivalent to Category.all(:conditions => {:id => 1}})
Category.where(:id => 1).first
# Is equivalent of Category.first(:conditions => {:id => 1}})
The objects are only retrieved when special methods like first, each etc are called. This is called lazy loading which is a great when you want to cache your views. Read more about why here.
Category.where(:id => 1).recipes
Returns an array. If you simply do Category.where(:id => 1).first.recipes it should work.
But if you are just doing a where against the id, use the find method
Category.find(1) will return a Category object.
So:
Category.find(1).recipes

Resources