Get a hash of old attribute values from rails active record - ruby-on-rails-3

I want to generically access the old attributes that have changed in a model - that is, I want to get a hash of the old attributes values. My code is interested in all attributes that have changed, which may be a different set each time it's run.
I know you can get an array of changed attribute names with
model.changed
and I know you can do
model.attribute_was
to get the old value of an attribute if you know the name, but I can't find a way to programatically combine the two or to otherwise get the set of old values
I'm using it to create news stories about objects, eg
User 'Bob' changed x from a to b

You can use the attributes hash to generate this array:
old = model.changed.map{|attr| model.send("#{attr}_was".to_sym) }

Related

Compute many2many field with values from another model using Odoo developer interface

I need a new field inside Contact model that would hold information about Allowed companies of the related user.
Now there is only field about Currently picked company by that user (and it is not enough for me to make a record rule).
The field I want to copy values from is inside model Users and it is called company_ids.
I’m trying to add this field in the developer mode (Settings > Technical > Fields) like this:
But I’m having trouble with code that would fill my field with values from the another model.
for record in self:
record[("x_company_ids")] = env['res.users'].company_ids
I’m guessing that the record is referring to a record inside Contact model and it does not contain fields from another models like Users. So I can’t figure it out how to reference a field from another model.
Something similar to this: env['res.users'].company_ids?
It is even harder for me because it is many2many field and should always update when the source changes.
Maybe better solution would be to use Automatic action to write values to this field?
I saw some threads like this: Computed many2many field dependencies in Odoo 10.
But it seems like in those cases they had clear connection between the fields and I don't have it. I don't know how to get related user while I'm inside Contact model. I know only how to this oposite way (from user to contact): user.partner_id.id
Here in below given code you haven't specified related user from which you will get company_ids, you have directly accessing company_ids
for record in self:
record[("x_company_ids")] = env['res.users'].company_ids
You can write as following :
for record in self:
record["x_company_ids"] = self.env['res.users'].search([('partner_id','=',record.id)]).company_ids

How to get text field history in selenium?

Is it possible to get a field's history (if it exists) for a field in an array or something of that sort in selenium? For example, user id field, I can see all IDs that have been used so far.
The purpose I'd like to use this is quickly create new IDs that haven't been used before. For example testID45 is already taken, so I'll use testID46 to create a new one. It's a lazy way to fill out a form without keeping track of the taken IDs.
I don't fully understand why you want to create IDs using Selenium. If you would post more info on what problem you are trying to solve, I could try to provide a better answer.
If you want to pull the IDs from existing elements you could do something like this. This finds all INPUT elements that have an ID specified and writes out the IDs. You could parse the IDs and then determine which ID to use next. I wouldn't recommend this because it would be faster to just generate a new ID that will be unique but maybe you need this for some reason.
List<WebElement> ids = driver.findElements(By.cssSelector("input[id]"));
for (WebElement id : ids)
{
System.out.println(id.getAttribute("id"));
}
I would recommend generating a new ID of your own format that would be unique on the page. This should be good enough for your purposes.
Random rnd = new Random();
String id = Long.toHexString(rnd.nextLong());
System.out.println("testID-" + id); // e.g. testID-cb8e7bac29ec7c7a
There are many other methods of generating strings in this post that you can reference also.

Remove object from Active Record Relation without deleting it

I'm working in Ruby on Rails 4 with Postgresql, and I've hit a bit of a snag. We have an Active Record model called AttendanceRecord which belongs to an AttendanceDay, AttendanceSwipe, Course, and CourseTimeSlot. Attendance Records were supposed to be unique on these fields, but something went wrong and duplicates snuck in. So, I wrote a method to find all of the Attendance Records which were duplicated and only keep one of them.
In the course of that method, I built an Active Record Relation of objects that shared the same attributes, like so:
records = AttendanceRecord.where(course_id: attributes[0], course_time_slot_id: attributes[1], attendance_swipe_id: attributes[2], attendance_day_id: attributes[3])
Nice relation, right?
Next, I found the object that I wanted to keep and named it to_keep. Then, I tried to remove just that object from the relation, like this:
records.delete(to_keep)
Unfortunately, I discovered that the delete method works a little differently on a Relation than it does on an Array. Instead of simply removing the object from the list, it actually does delete it from the database (without the callbacks).
So: I'm wondering if there is a method that I'm missing that will remove my to_keep object from the Relation without actually touching the object itself. Then, I'll be able to safely call records.destroy_all and happily go about my business. :)
If you want to exclude an object from a relation you can do so by id. For example:
records.where('id <> ?', to_keep.id).destroy_all
or, thanks to #trushkevich, in rails 4 you can do:
records.where.not(id: to_keep.id).destroy_all
This means that destroy_all will be called on the records you've identified already but excluding the to_keep record.

What is the best way to fake a SQL array or list?

I'm building a chatroom application, and I want to keep track of which users are currently in the chatroom. However, I can't just store this array of users (or maybe a list would be better) in a field in one of my records in the Chatroom table.
Obviously one of the SQL data types is not an array, which leads me to this issue: what is the best way to fake/mock array functionality in a SQL database?
It seems there are 3 options:
1: Store the list/array of users as a string separated by commas, and just do some parsing when I want to get it back to an array
2: Since the max amount of users is allowed to be 10, just have 10 extra fields on each Chatroom record representing the users who are currently there
3: Have a new table Userchats, which has two fields, a reference to the chatroom, and a user name
I dunno, which is the best? I'm also open to other options. I'm also using Rails, which seems irrelevant here, but may be of interest.
Option 3 is the best. This is how you do it, in a relational schema. It is also the most flexible and future-proof option.
It can grow easier in width (extra columns say, a date joined, a channel status, a timestamp last talked) and length (extra rows when you decide there now can be 15 users in a room instead of 10).
The proper way to do this is to add an extra table representing an instance of a user being in a chatroom. In most cases, this is probably what you will want to do, since it gives you more flexibility in the types of queries you can do (for instance: list all chatrooms a particular user is in, find the average number of people in each chatroom, etc.) You would just need to add a new table - something like chat_room_users, with a chat_room_id, and a user_id.
If you're deadset on not adding an extra table, then Rails (or more specifically ActiveRecord), does have some functionality to store data structures like arrays in a SQL column. Just set up your column as a string or text type in a Rails migration, and add:
serialize :users
You can then use this column as a normal Ruby array / object, and ActiveRecord will automatically serialize / deserialize this object as you work with it. Keep in mind that's there are a lot of tradeoffs with this approach - you will never be able to query what users are in a particular room using SQL and will instead need to pull all data down to Ruby before working with it.

How do I get NHibernate to save an entity if I assign it an ID, but generate one otherwise?

According to the REST philosophy, a PUT request should update the resource at a URL if it exists, and create it if it doesn't exist. So in other words, if I use the following URL:
PUT http://server/item/5
If an Item exists with an ID of 5, it will be updated. If an Item doesn't exist with an ID of 5, a new Item will be created with an ID of 5.
However, I'm using NHibernate for persistence, and I mapped my IDs as Identity. This means that no matter what value I assign the ID, NHibernate will replace it with its own when I save a new Item.
How do I get NHibernate to save an Item with the ID that I assign it, without changing the ID mapping to Assigned?
If you use Identity, the DB won't allow you to enter a value.
That said, if your DB has some special syntax to allow inserting with explicit values in Identity fields, you can implement your own generator, which I guarantee will be error prone, hard to debug, and not very useful. But it's possible.
Study everything in https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Id and start creating your Frankenstein :-)