Ruby Active Record join with condition - ruby

I have a column in the Tooltype table called "deleted" which can be true or false. I only want the records which are false. I somehow only manage to check for the second table (toolunits) but not for the first (tooltype). So this WOULD work if I had a column "deleted" in my toolunits table:
obj = Tooltype.joins(:toolunits).where(toolunits: {deleted: false}).distinct
But this does not (see third line):
get '/api/tooltypes' do
if params['selector']
obj = Tooltype.joins(:toolunits).where(tooltype: {deleted: false}).distinct
else
obj = Tooltype.joins(:toolunits).distinct
end
obj.get_list() do |q|
if params['selector']
q.where(deleted: false)
end
end.serialize.first
end
How can I use the condition on the first table?

I'm thinking about two ways
Tooltype.joins(:toolunits).where(Tooltype.table_name => {deleted: false})
Tooltype.joins(:toolunits).where('tooltypes.deleted = ?', false)

Related

Ruby - How to filter SQLite rows based on column conditions

I have a variable session[:pet_profile_tags] that returns an array like ["adult", "activity_low", "overweight"].
I then have an SQLite database, called balto.db, which contains the table pet_tips. That table contains 2 columns, "ID" (Integer) and "C1_inclusion" (VARCHAR).
For each row of the pet_tips table, I need to check if the value contained in the C1_inclusion column contains one of the values of the session[:pet_profile_tags] array variable. If that is the case, I need to check the row's ID and store it inside another array variable, named pet_tips.
I tried the below code but I am getting the following error: TypeError - no implicit conversion of String into Integer: index.rb:428:in '[]' , line 428 being if (session[:pet_profile_tags].include?(row["C1_inclusion"].to_s))
# Assign pet tips
pet_tips = []
# Query the pet_tips table
db = SQLite3::Database.open "balto.db"
rows = db.execute("SELECT * FROM pet_tips")
# Iterate through each row of the table
rows.each do |row|
# Check if the row matches the C1_inclusion column
if (session[:pet_profile_tags].include?(row["C1_inclusion"].to_s))
# If the row matches, add the ID to the pet_tips array
pet_tips << row["ID"]
end
end
session[:pet_tips] = pet_tips
db.close
I have been stuck for hours, any help would be really appreciated!
First I tried returning the value of the session[:pet_profile_tags] variable to make sure I was getting the correct array. Then, I made sure to check that the different column and variable names where correctly referenced in my code.
Error
Your error is here: row["C1_inclusion"]
row is an Array of values in column order e.g. [1,"adult"].
Array#[] expects an Integer (index) but you are calling it with a String ("C1_inclusion")
Solutions
To solve this you can
Option 1:
Use Integer indexes based on column order
if (session[:pet_profile_tags].include?(row[1]))
pet_tips << row[0]
end
Option 2: convert the row to Hash:
Always:
db = SQLite3::Database.open "balto.db"
db.results_as_hash
rows = db.execute("SELECT * FROM pet_tips")
rows.each do |row|
if (session[:pet_profile_tags].include?(row["C1_inclusion"]))
Just for this loop:
rows.each_hash do |row|
if (session[:pet_profile_tags].include?(row["C1_inclusion"]))
Option 3: Query just the data you want.
# Query the pet_tips table
db = SQLite3::Database.open "balto.db"
session[:pet_tips] = db.prepare("SELECT ID FROM pet_tips WHERE pet_tips.C1_inclusion IN (?)")
.execute!(session[:pet_profile_tags].map {|s| "'#{s}'"}.join(","))
.flatten
db.close
This uses session[:pet_profile_tags] as a WHERE condition against pet_tips.C1_inclusion and assumes you have control over this variable (e.g. does not perform escaping)

Excel PowerQuery: how do I add an IsNotNull column

I have a simple function that I'd like to run on the values in a column, resulting in another column.
let
ThisIsNotNull = (input) => if (input = null) then false else true,
Source = ...
eventually there is a text column with Nulls in it, let's call it TextColumn.
I'd like to add another column alongside it with a value of =ThisIsNotNull(TextColumn).
Add column... Custom column with formula
= ThisIsNotNull([NameOfColumnToTest])
But really you can skip the function and just use
= if [NameOfColumnToTest] = null then false else true

appending to rails field value

I need to find and update a number of records in a Rails 3.2, Ruby 2 application. The following code successfully finds the records I want. What I need to do though is add " x" (including the space) to the email address of every user and I can't figure out how to do it.
This finds the records
User.joins(:account)
.where("users.account_id NOT IN (?)", [1955, 3083, 3869])
.where("accounts.partner_id IN (?)", [23,50])
.where("users.staff = '0'")
.where("users.admin = '0'")
.where("users.api_user = '0'")
.where("users.partner_id is null")
.update_all(email: :email.to_s << " X")
but it's the last line I'm having problems with. Is this possible, or do I need to find the records another way?
The update_all method updates a collection of records, but unless you write your own SQL expression, it can only set one value. For example, if you wanted to overwrite all the email addresses with "X", you could do it easily:
User.joins(:account)
.where("users.account_id NOT IN (?)", [1955, 3083, 3869])
# ...other scopes...
.update_all(email: "X")
In your case, what you really need to do is make individual updates to all these records. One way to do it is to find the records, then loop over them and update them one at a time:
users_to_update = User.joins(:account)
.where("users.account_id NOT IN (?)", [1955, 3083, 3869])
.where("accounts.partner_id IN (?)", [23,50])
.where("users.staff = '0'")
.where("users.admin = '0'")
.where("users.api_user = '0'")
.where("users.partner_id is null")
users_to_update.each do |user|
user.update_attribute(:email, "#{user.email} X")
end
Another solution would be to use a SQL expression with update_all, as in Zoran's answer.
Try writing the last line like so:
.update_all("email = email || ' X'")
This uses SQL's string concatenation operator to append the X to the end of the emails.
Hope that helps!

VB6.0 with DataControl Database Programming

Hey, can I ask you something? I'm using VB6.0 and I have some problem with the connection of my Database through DataControl. I have a table named tblEmployee and the other one is tblPosition then I passed the value of the two tables to two DataControls respectively. How can I then get the value of a certain row of Position field. With my code, my Position field returns only the first row. Here's my code
Private Sub cmdSearchEmployee_Click()
With datEmployee.Recordset
datEmployee.Recordset.Index = "idxid"
datEmployee.Recordset.Seek "=", txtIDNumber.Text
If .NoMatch = True Then
MsgBox ("No Record Found!")
Else
Me.txtLastName.Text = .Fields("lname")
Me.txtFirstName.Text = .Fields("fname")
Me.txtMiddleName.Text = .Fields("mi")
With datPosition.Recordset
Me.txtPosition.Text = .Fields("position")
End With
End If
End With
End Sub
I can't see that you have "passed the value" to your DataControl named datPosition. Could this be the problem? e.g. where you have
With datPosition.Recordset
Me.txtPosition.Text = .Fields("position")
End With
...should be more like this:
With datPosition.Recordset
.Index = "some_index??"
.Seek "=", "some_value??"
Me.txtPosition.Text = .Fields("position")
End With
Also consider using the recordsets' Filter to remove the rows that do not match your criteria then RecordCount to loop through the rows that do match your criteria.
Further consider returning a single recordset by creating a join between tblEmployee and tblPosition, either in SQL code or returning a hierarchical recordset using the MsDataShape with its SHAPE syntax.

get last insert id when using Activerecord

For Sqilte3 C API, I would use sqlite3_last_insert_rowid. How to get this id when using ActiveRecord after insert a new record? I use following way to insert a new record :
Section.new |s|
s.a = 1
s.b = 2
#I expected the return value of save to be the last_insert_id, but it is NOT
s.save
end
'save' method returns true or false based on if saving was successful or not
try smth like:
new_section = Section.new do |s|
s.a = 1
s.b = 2
s.save
end
p new_section
it should print all fields you set manually plus any automatically filled values, including last_insert_id being usually the record 'id'
Assuming you've used the ActiveRecord default field name to hold the primary key, then s.id will hold the id of the record you've just saved.

Resources