How do you query Active record with enums - activerecord

I am trying this query and it is not working:
OrderFulfillment.where(shopper_id: shopper.id, fulfillment_status: [:fulfillment_requested_assignment, :fulfillment_assigned, :fulfillment_shopping])
I am not sure why but I am unable to get querying using enums to work

OrderFulfillment.where(shopper_id: shopper.id,
fulfillment_status: OrderFulfillment
.fulfillment_statuses
.values_at([:fulfillment_requested_assignment,
:fulfillment_assigned,
:fulfillment_shopping]))
Rails isn't smart enough to know that you are passing keys and not values, so when you were passing the statuses straight like that it was looking for the wrong values (it changed them to null because it didn't understand). The enums are physically stored as integers, so that's what you actually need to use in the query. Therefore, you can use the Rails-provided fulfillment_statuses method to grab a hash of the key/value pairs of the enum, and then the values_at method of the hash to get the values for the array of keys you pass in.

Related

How can I store multiple elements in a Rust HashMap for the same key?

I have a HashMap<u32, Sender>. Sender is a open connection object and the key is a user id. Each user can connect from multiple devices. I need to store all possible open connections for the same user id. After this I can iterate and send messages to all open connections for same user.
The above HashMap only stores each user id and connection once. I need to get one key with multiple values. How can I make the value into a list or an array, so I can see which connections exist and send to them all?
I am not talking about different value types, like enums. I am talking about the same type values but more than one. Maybe HashMap is not designed for this?
Alternative ideas are also welcomed.
To do this with a HashMap you should use a Vec as the values, so that each key can point to multiple Senders. The type then would be HashMap<u32, Vec<Sender>>.
Using this structure, just using insert() can get clunky when you need to mutate the values like this, but instead you can use the Entry API for retrieving and updating records in one go. For example:
let mut hash_map: HashMap<u32, Vec<Sender>> = HashMap::new();
hash_map.entry(3)
// If there's no entry for key 3, create a new Vec and return a mutable ref to it
.or_default()
// and insert the item onto the Vec
.push(sender);
You could also use the multimap crate, which does something similar under the hood, but adds a layer of abstraction. You might find it easier to work with:
let mut multi_map = MultiMap::new();
multi_map.insert(3, sender_1);
multi_map.insert(3, sender_2);
The method multi_map.get(key) will the first value with that key, while multi_map.get_vec(key) will retrieve all of them.

Python OpenSSL: How to create an X509Name object

I need to filter incoming X509 certificates by issuer, and I am using Pyhton's OpenSSL.crypto for this. However, I did not find how to create an X509Name object as a constant, which I need to compare with the value I get from cert.get_issuer().
Best thing I can think of, for you to create a new X509Name is to use
name = crypto.X509Name(crypto.X509().get_subject())
and subsequently populate the attributes via
name.__setattr__(att_name, attr_value)
However, for comparison alone, better to use the hash() builtin function of the class, that returns a hash for the whole name, or do a per-attribute comparison

how to check for an attribute in an array in ruby-on-rails

I need to find whether a specific attribute is present or not with where statement that takes an array in ruby.
I tried like the below.
User.where(id: [1,2,3]).include?('address')
User.where(id: [1,2,3]) would return a relation (which behaves pretty much as an array, but that's another story). It means, that is consists of objects - instances of User class.
You check if this collection includes string ('address'). It is not, as you may guess by now.
If you need to map all users by address, you can use pluck:
User.where(id: [1,2,3]).pluck(:address)
You could use: User.where(id: [1,2,3]).map(&:address) which will return an array containing the addresses.
And you can use User.where(id: [1,2,3]).map(&:address).map(&:present?) if you want an array with true or false value

Add new attribute to existing hash

I am retrieving results using Mongoid, but I want to add a new attribute to each of the records returned in an instance variable using the key. How would I go about doing this?
In PHP I would do this by looping through the array and inserting it based on the key of the object. I am unable to figure out how this can be done in Ruby when I receive the message: Model ABC can't be converted into an Integer.
Update: I ended up adding a method in the model to achieve what I was trying to do.
I'll try to point you in the right direction.
If you have an array of records and what to loop through it, use Array#each: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-each
You can write attributes easily: http://rdoc.info/github/mongoid/mongoid/Mongoid/Attributes#write_attribute-instance_method
Hope that helps

how to group objects in an array Ruby

I have an array of users who are managers.
However there are repeated Users.
I would like to group them so that there is only one instance of each User in the array.
What would be the best way to go about this?
#managers.sort_by{|obj| obj.id} # Just sorted the data but did not eliminate duplicats
#managers.group_by{|u|u.name} # just created a bunch of arrays for each name
Use the uniq method, which returns a new array with duplicates removed.
#managers.uniq
If by duplicate you mean the same object ID, then you can do the following:
#managers.uniq.group_by(&:name)
Filtering the array feels like fixing symptoms. Why does the array contain rubbish in the first place?
I would suggest adding a manager? method to your User model that returns true if the user is a manager. Then you could to something like
#managers = User.select &:manager?
and get an array that only contains managers.
you can also do
Manager.select('DISTINCT user_id')
to get a clean array in the first place, whith better performance.

Resources