How to get the date when the particular attribute was first changed in rails - ruby-on-rails-4

I have a boolean atrribute whose default is false. How can i get the date when the attribute was changed to true?
The is_changed gives you if the value was changed. I want the date when the attribute was first changed.
How do i get it in rails?

add attribute 'first_change' in that table which will save time stamp of every first change of the boolean attribute changed to true or false, then in model write the callback like this
before_update :check_changes
def check_changes
if self.<boolean_attribute>.is_changed? and first_change.nil?
self.update(first_change: Time.now)
end
end
After this you can check when the boolean attribute was changed.

You can wrap your boolean attribute in distinct model and from there you can easily trace when specific field was initially setted up or updated. In your current model you can't trace changing state of specific attributes, only the whole object, but it's not what you need I guess.

Well, looks like you basically want the feature of git in ActiveRecord records.
There are two ways
Use a separate col like changed_date. Update it whenever the field is changed for the first time.
I recommend this if your requirement is that simple. Do not use heavier gems.
Use libraries like VestalVersion or PaperTrail
these are helpful to track every activity in your records.
you can keep track of every changes, what its changed to and when
also you can revert your record to any point of time it was changed

I think there are two ways like above answer suggested to make a separate field and add date there when field changed first time or
you can use Public Activity gem that will log all the model activity with params.
It creates a activities table based on this table you can get the date of the fields when it was first changed but it is a lengthy process

Related

Get part of django model depending on a variable

My code
PriceListItem.objects.get(id=tarif_id).price_eur
In my settings.py
CURRENCY='eur'
My Question:
I would like to pick the different info depending on the CURRENCY variable in settings.py
Example:
PriceListItem.objects.get(id=tarif_id).price_+settings.CURRENCY
Is it possible?
Sure. This has nothing to do with Django actually. You can reach the instance's attribute through pure Python:
getattr(PriceListItem.objects.get(id=tarif_id), 'price_'+settings.CURRENCY)
Note it might be a better idea to have a method on the model which accepts the currency as a parameter and returns the correct piece of data (through the line I wrote above, for example).
I think this should work
item = PriceListItem.objects.get(id=tarif_id)
value = getattr(item, price_+settings.CURRENCY)
In case you are only interested in that specific column, you can make the query more efficient with .values_list:
my_price = PriceListItem.objects.values_list_(
'price_{}'.format(settings.CURRENCY),
flat=True
).get(id=tarif_id)
This will only fetch that specific column from the database, which can be a (a bit) faster than first fetching the entire row into memory, and then discard all the rest later.
Here my_price is thus not a PriceListItem object, but the value that is stored for the specific price_cur column.
It will thus result in a query that looks like:
SELECT pricelistitem.price_cur
FROM pricelistitem
WHERE id=tarif_id

Count method to total up the records with a boolean field set to a particular state. RoR

I’m trying to use the .count method to total up the records with a boolean field set to a particular state.
For example, a blog’s Post table has a field named posted_at which has a null value when the post has not yet been posted (draft only) and contains a timestamp when the post has been posted.
Running #posts.count returns the total number of posts, as expected
Running #post.posted? returns the posted_at field’s state, as expected
However running #posts.posted.count fails with a method_missing error
I have tried posted?.count and get the same.
It seems that ActiveRecord was smart enough to figure out that when targetting one record, posted? should check the state of the posted_at field without a posted? method being defined in the model. Is it also smart enough to know what we are trying to do when adding a .count method into the mix or do we need to define it as a method?
There is no automatic method created by ActiveRecord to do this, but you could use a scope for this purpose, by adding this to your Post model:
scope :posted, -> { where.not(posted_at: nil) }
Then, you will be able to do this anywhere:
#posts.posted.count

How to make a date field to be autopopulated in Siebel CRM Desktop?

Whenever I create a new activity, I need a date field to be autopopulated ( it will be autopopulated but greyed out until and unless a checkbox next to it needs to be checked).
I perform a validation based on the date field, when a new activity is created. since the date field check box is not checked, it is not considering the value for the validation.
Any help or suggestion is appreciated.
Thanks.
Jaya Vignesh.
make use of predefault and postdefault values to populate current-date.
set field Read-only (BC field user property). You can find it under Business Component in object explorer.
Field read-only allows you to make a field read-only based on value of other field from same BC or joined field.
I perform a validation based on the date field, when a new activity is created. since the date field check box is not checked, it is not considering the value for the validation.
This requirement of yours isn't clear what exactly you want to validate. Since you are populating it bydefault, I don't find the significance in validating your own auto-populated data. well yet I provide a suggestion below
There are two types of validations, 1. Using configuration or 2. Using scripting. I am not pretty much sure if it can be achieved with configuration but scripting it is possible by overriding BusComp_presetFieldValue, BusComp_preWriteValue. The first one executed when you populate a field. And the latter one when you commit the record.
I have answer assuming your requirement. Let me know if you have any questions or clarifications required.
You can add the Predefault property of the field to be the following
System: TimeStamp

Django partial update

I have two threads, one which runs something like update t set ColA=foo and the other runs update t set ColB=foo. If they were doing raw SQL statements there would be no contention, but since Django gets and saves the entire row, a race condition can occur.
Is there any way to tell Django that I just want to save a certain column?
Update old topic.
Now, we have update_fields argument with save:
If save() is passed a list of field names in keyword argument
update_fields, only the fields named in that list will be updated.
https://docs.djangoproject.com/en/stable/ref/models/instances/#specifying-which-fields-to-save
product.name = 'Name changed again'
product.save(update_fields=['name'])
You are correct that save will update the entire row but Django has an update which does exactly what you describe.
https://docs.djangoproject.com/en/stable/ref/models/querysets/#update
I think your only option to guarantee this is to write the raw SQL by hand by using Manager.raw() or a cursor depending on which one is more appropriate.

Django - Insert Without Returning the Id of the Saved Object

Each time the save() method is called on a Django object, Django executes two queries one INSERT and one SELECT. In my case this is usefull except for some specific places where each query is expensive. Any ideas on how to sometimes state that no object needs to be returned - no SELECT needed.
Also I'm using django-mssql to connect to, this problem doesn't seem to exist on MySQL.
EDIT : A better explanation
h = Human()
h.name='John Foo'
print h.id # Returns None, No insert has been done therefore no id is available
h.save()
print h.id # Returns the ID, an insert has taken place and also a select statement to return the id
Sometimes I don't the need the retruning ID, just insert
40ins's answer was right, but probably it might have higher costs...
When django execustes a save(), it needed to be sure if the object is a new one or an existing one. So it hits the database to check if related objext exists. If yes, it executes an UPDATE, orherwise it executes an ISERT
Check documentatin from here...
You can use force_insert or force_update ,but that might be cause serious data integrity problems, like creating a duplicate entry instead of updating the existing one...
So, if you wish to use force , you must be sure whether it will be an INSERT or an UPDATE...
Try to use save() method with force_insert or force_update attributes. With this attributes django knows about record existence and don't make additional query.
The additional select is the django-mssql backend getting the identity value from the table to determine the ID that was just inserted. If this select is slow, then something is wrong with your SQL server/configuration because it is only doing SELECT CAST(IDENT_CURRENT(*table_name*) as bigint) call.