I have a problem with active_record query, sorry, I'm new with rails.
I have a model Subscription, it has child SubscriptionVersion, where I keep all info that can be updated.
At API calls, for example get request, I merge data from subscription and current version (#subscription.subscription_versions.last) and give that merged hash for response, but I've faced with problem of sorting and filtering by values in that current_version.
When I try do that
#subscriptions.joins(:subscription_versions).order('subscription_versions.version') it takes all version and sort by min value, even if subscription has 5 versions and latest is 5th (current_version).
So ... can anyone give me advice how to generate query for that without adding new field in subscription model current_version_id?
If I understand correctly, you want only to return the last subscription_version?
Depending on how the versions are sorted, you could do this (Haven't tested this):
#subscriptions.joins(:subscription_versions).order('subscription_versions.version').first
or
#subscriptions.joins(:subscription_versions).order('subscription_versions.version').last
Related
I have a model which I want to store a history of changes to, my plan is to rather than update an object create a new one and on a show only fetch the latest version.
This plan presents a number of difficulties firstly the id will be different after a update I indend to get around this by keeping a second ID column which will be the same for all updates of that instance.
to that end I have created a SQLite sequence for this second coloumn.
my question is how can I get values from this sequence in the model/controller as I will only want to get from it on first time the object is created, secondly how can I use this second ID column as the URL for the object so it is fixed throughout updates.
Many Thanks,
Check out the PaperTrail gem. It might do what you want and sidestep those issues completely.
https://github.com/airblade/paper_trail
I'm looking into an issue where the Refund button isn't available for orders that were placed prior to an upgrade of a client site from 1.3 to 1.7. I'm attempting to create a credit memo from Sales Order > Invoice > Credit Memo.
Drilling into the code and data, it seems that $this->getCardsStorage() is not returning any stored credit cards for order payments made prior to the upgrade. In fact, the additional_information field in the sales_flat_order_payment table is NULL for those orders - I believe that field was created in 1.4 or later.
The thing that seems odd to me is that there would be no backwards compatibility for payment data created prior to 1.4. I've done a decent bit of searching for this problem and the closest thing I can find is where people are having problems with refunds entirely after upgrading. That's not the case for me - refunds appear to be working fine for post-upgrade orders.
If it is the case that there simply is not backwards-compatibility, it would be good to at least see a bug report on it.
I posted this to the magento bug tracker: Bug #28601
That's true, there is a problem with it in 1.4 upgrades.
In 1.4 were introduced transactions and were used additional_information field, there were different field before, called additional_data, that was also serialized, but in different manner, you can look up for payment record before 1.4 and after 1.4 to compare how the data structure is changed. And when you will see the difference in data, you can create a script that will migrate old values.
Sincerely,
Ivan
UPDATE
Check the following code:
https://github.com/LokeyCoding/magento-mirror/blob/magento-1.3/app/code/core/Mage/Paygate/Model/Authorizenet.php
During authorization process, transaction id is stored in both properties:
cc_trans_id and last_trans_id. When customer perform a capture only last_trans_id get updated.
In 1.3 method getRefundTransactionId() was returning last_trans_id value.
In 1.7 the same method is looks like the following:
https://github.com/LokeyCoding/magento-mirror/blob/magento-1.7/app/code/core/Mage/Paygate/Model/Authorizenet.php
So you see it is completely rewritten!
For making your 1.7 code work for 1.3 transaction, you need to do the following for old transactions:
If last_trans_id == cc_trans_id and order has invoice, then create only capture transaction record in order_payment_transaction table.
If last_trans_id == cc_trans_id and order does not have invoice, create authorization transaction record
If last_trans_id !== cc_trans_id create 2 records, first with cc_trans_id and it will be auth transaction and second one will be a child transaction with capture type.
When you will export this old orders with such values, you will be able to refund old order from the admin.
in the application i am currently creating in ruby on rails. I am trying to do some tests in rails console where i have to destroy data in the database and the database is connected to a server. I am importing an XML and parsing it and putting it into a database with scaffolding.
Now what i need: Basically what i am attempting to do is to destroy the data and replace it with a new one every week..but the problem i am getting, the userid is gone up to 700+ and there are only 50 records :S cause it doesnt reset...
To delete all records i am currently using "whatever.destroy_all" does the trick
Any help?
Btw i am using SQLITE
The ID column created in the table usually is set as unique and to increment by 1 for each new record, which is why each time you destroy and add new data the ID keeps getting higher.
The fact that the ID # is getting larger and larger is not an issue at all.
If you really want to start back at zero, I would think you could drop the table and recreate it, but that seems like overkill for a trivial issue.
Regarding the connection to the other scaffold, how are you connecting the two and what do they both represent?
Ideally the data population for testing should be done through fixtures (or easy tools such as factorygirl etc..)
The main advantage of having a fix data set is you can run your tests in any environment. But as per your requirement you can do something like this,
When you populate the date through the active records pass the id parameter as well
Ex: User.new(:id => 1, :name => "sameera").create
By this way you can have constant id's But make sure you increment the id accordingly.
I am using AR-Extensions to import a large number of objects to db, but synching them back from DB just isn't working.
MY code:
posts = [Post.new(:name=>"kuku1"), Post.new(:name=>"kuku2"), ...]
Post.import posts, :synchronize=>posts
posts are submitted to db, and each one is allocated with primary key (id) automatically. But when afterwards checking the objects in posts array, I see that they don't have id field, and new_record flag is still true.
I also tried adding :reload=>true, but that doesn't help as well.
Any idea why synch doesn't work?
This is not possible right now with new records. As of ar-extensions 0.9.3 this will not work when synchronizing new records as synchronizing expects the records you're sync'ing to already exist. It uses the primary key under the covers to determine what to load (but with new records the primary key is nil). This limitation* also exists in activerecord-import 0.2.5. If you can synchronize on other conditions I'd be happy to release a new gem allowing conditions to be passed in. For Rails 3.x you need to use activerecord-import though (it replaces ar-extensions). Please create ticket/issue on github: https://github.com/zdennis/activerecord-import/issues
For Rails 2.x you still want to use ar-extensions, and I'd likely backport the activerecord-import update and push out a new gem as well. If you'd like this functionality here please create a ticket/issue on github: https://github.com/zdennis/ar-extensions/
Patches are welcome as well.
*The limitation here is a database constraint, as its impossible to get the ids of all newly created records after a single insert/import without doing something strange like table locking, which I don't think is a good solution to that problem. If anyone has ideas I'm all ears.
UPDATE
activerecord-import 0.2.6 and ar-extensions 0.9.4 have been released and includes support for specifying the fields you want to synchronize on. Those fields should be unique. See http://www.continuousthinking.com/2011/4/6/activerecord-import-0-2-6-and-ar-extensions-0-9-4
What would be the rails way of implementing version control in my record management application?
My system allows users to manage Records and i want to allow them to view historical versions of a Record. i know instead of updating a Record I will now create a new instance of the Record and related models every time a user "updates" a record(each Record has_many Categories and Advantages). how would i ensure that different versions of the Record are all linked together (i.e the new updated record created to be associated as the new version of record A, so when i click "show me a list of all versions of record A").
this is all theoretical thinking as i am yet to start coding, if i missed anything which i should also consider please let me know.
Thank You
create a new instance of the record every-time a user updates it, have a secondary ID as you mentioned to group all different versions of the same record together and then run a check in the controller (using some sort of hidden value) to see if you want to save over the record or create a new one.
You can then retrive the latest version of each record by finding the most recently updated/created record with a unique secondary_id.
A good starting point may be the vestal versions gem, that keeps an history of modified records
Here are 2 of my insights:
1st simple one :
You save a record with a higher id , when you read it you take the higher id. If you want to know the past do not filter on ids.
2nd (parts from SAP) :
Your record has 2 supplemental fields , that is startTime, stopTime. Thoses are the time the record start entering in action and stops being in action. Inserting a new record , you update the stopTime of the last one, put now as the startTime of the new one, and the end of the world for the stopTime of the new one