Rails 3 after_save old value - ruby-on-rails-3

How do you work with the old values of a record being updated?
For instance in the following code block how would I run a query using the previous winner_id field after I determine that it has indeed changed?
if self.winner_id_changed?
old_value = self.changed_attributes
User.find(old_value)
#do stuff with the old winner....
end
An example output of self.changed_attributes would be:
{"winner_id"=>6}
Do I really have to convert this to a string and parse out the value in order to perform a query on it? old_value[:winner_id] doesn't seem to do anything.

Use where instead of find, and the following inject method on changes to generate the desired hash:
if self.winner_id_changed?
old_value = self.changes.inject({}) { |h, (k,v)| h[k] = v.first }
old_user = User.where(old_value)
#do stuff with the old user....
end
You can also use ActiveRecord dirty methods such as:
self.winner_id_was
to get specific attribute's old value. Full documentation may be found here.

Related

Rails: How to use instance method in Active Record Query

I am having a filter query which should return all the records where either
attribute (column) "status" is not "done", or
instance method "completeness_status" does not return "done"
The query is something like that:
Studies.where("studies.status != ? OR studies.completeness_status != ?", "done", "done")
but I am getting error that column completeness_status does not exist.
Unfortunately, the column status is not continuously updated, so I cannot use it only. Also, the instance method "completeness_status" is based on records from other tables.
I try to add a scope to my model and use this instance method as scope but also I was not successful.
Also, I tried to used it as class method but then I do not know how to call it from where clause.
def self.completeness_status(study)
# code
end
or
def self.completeness_status_done?(study)
# code return true or false
end
Any Idea how to solve that.
Thanks.
You cannot use instance methods inside your query. But if you like to check the condition of completeness for only one row, then you can use it as instance method:
first_study = Study.first
first_study.completeness_status_done?
Also, if you provide more information about what is going on inside your completeness_status_done? then maybe I can give you some ideas to use scopes.
https://guides.rubyonrails.org/active_record_querying.html

Default values for query parameters

Please forgive me if my question does not make sense.
What im trying to do is to inject in values for query parameters
GET1 File
Scenario:
Given path 'search'
And param filter[id] = id (default value or variable from another feature file)
POST1 File
Scenario:
def newid = new id made by a post call
def checkid = read call(GET1) {id : newid}
like if one of my feature files creates a new id then i want to do a get call with the above scenario. therefore i need a parameter there which takes in the new id.
On the other hand if i do not have an id newly created or the test creating it is not part of the suite. i want to still be able to run the above mentioned scenario but this time it has a default value to it.
Instead of param use params. It is designed so that any keys with null values are ignored.
After the null is set on the first line below, you can make a call to another feature, and overwrite the value of criteria. If it still is null, no params will be set.
* def criteria = null
Given path 'search'
And params { filter: '#(criteria)' }
There are multiple other ways to do this, also refer to this set of examples for data-driven search params: dynamic-params.feature
The doc on conditional logic may also give you some ideas.

Orientdb sql auto increment: id is always null (sql batch, update increment, variables)

I was looking at another question in stackoverflow regarding auto increment fields in orientdb, where one of the answers was to create our own vertex with counter field.
However, when I'm trying to execute the following code (both java api and console script batch), It is not working.
Do note however that the id is returned good (did some debug attempts, returning the id variable only), and the vertex is created.
However, the vertex id is always null (unless I set it explicit, that is).
The script:
script sql
LET id = UPDATE CCounter INCREMENT value=1 RETURN AFTER $current WHERE name='session'
LET csession = CREATE VERTEX CDate SET id=$id.result, meet_date='2015-01-01 15:23:00'
end
I tried playing around with $id and $current , but nothing seems to work.
Currently I am doing it in a 2-transaction mode; one to get the id, and another to create the vertex. I really hope there is a better way though.
P.S.
I am using version 2.0-M2
You should execute
LET csession = CREATE VERTEX CDate SET id=$id.value, meet_date='2015-01-01 15:23:00'
Note the $id.value in place of $id.result.
As stated in a comment to Lvca, the answer was:
(1) Change the field name. Id seems to be reserved (ish). It's probably possible to still bypass it and use a field named 'id', but I didn't want to mess around with it.
(2) From some reason, the result was a collection (shown as '[id]'). It took me some time to figure it out, but I just had to choose the first value from it.
(3) Also, there are 2 'values' here. One of the field ($current.value), and the second one(not sure where it's coming from).
Final solution that works:
script sql
LET id = UPDATE CCounter INCREMENT value = 1 RETURN AFTER $current.value WHERE name='session'
LET csession = CREATE VERTEX CDate SET data_id=$id[0].value, meet_date='2015-01-01 15:23:00'
end

Add data from one table to another in ruby on rails

In my current project, I have to get some data in a column of one table and put them to the 2nd table. The first table data have been saved as hash as follows:
---
- werweqr
- test
- B1
- B2
- B3
- xvxczv
I write the following code in the migration file to add the data from the first table to the 2nd table. But the data are not sending from the first to second.
#scenario_response = ScenarioResponse.where("selected_barriers != ?", "");
#scenario_response.each do |p|
p.selected_barriers.each do |barrier|
Settings.test = barrier
# SelectedBarriers.create(:scenario_response_id => p.id, :barrier => barrier)
end
end
Can anyone please let me know if there's something wrong in my code.
If so how to fix it?
Thanks a lot
I don't think you need to call "each" on p.selected_barriers.Try removing the each and doing this:
Settings.test=p.selected_barriers.
I'm new to RoR too..According to me,the scenario_response is a collection that returns all instances that have the selected_barriers as "". Since you are doing an each on the collection, you will just have one selected_barriers item for each of them.
Please try this and let me know if I'm wrong.
Also you are not doing update_attributes.
Try doing Settings.update_attributes(params[:test]) after Settings.test = barrier .

ruby on rails store sql result on a variable

Newbie here. I am trying to store the result of my search onto a variable.
#answer = q.answers.select(:name) which runs
"SELECT name FROM "answers" WHERE "answers"."question_id" = 1;" and returns
"t" for true.
It runs fine on the command line and shows the right result. But I want to compare that result to another variable.
How do i extract that result? #answer[0], or #answer, or answer_var = #answer[0]
i.e.
if #answer == some_other_variable OR
if #answer[0] == some_other_variable OR
if answer_var == some_other_variable
what value do #answer[0] and #answer[0] hold and how can I print the value to the log file? not the web page. I know it must be simple, but I can't get my head around it.
Thanks.
It's not really an answer to your question but...
If you want to follow "the rails way", you should better use Models and not deal with SQL at all.
E.g. :
#answer = q.answers.first # answers is an array, take the first
if #answer.name == ...
For the logging, I suggest you that : http://guides.rubyonrails.org/debugging_rails_applications.html#the-logger