rails where query in multiple table - ruby-on-rails

I have a form which has fields from around three tables, and user can fill in any field and they can make a search.
For example i have these table and columns
Vehicle:
rego_num
make
model
vin
engine_num
transmission, ...
Customer:
name
surname
email_address
Address:
address1
address2
address3
phone
work_num
primary_num
fax
Vehicle belongs_to Customer
Customer has_one address
User can make search in any of the above mentioned fields, for ex they can enter rego alone and find serch or rego with make and model or name alone or with phone,
they can enter partial phone number and it should find it, phone is integer column.
I thought of finding vehicle column, if vehicle exist and then find customer, but the problem is they can enter customer fields alone.
I think i can write a joins and do a where query, like
vehicle.joins(:customer)
but address is related to vehicle, Can anyone suggest me how to send params to search method and write a query to find records
I checked pg_search gem it has one keyword to search against multiple columns, but i have multiple value to search against the particular column.

You can use ajax call to send parameters, and in controller you need to create a query with sql.
eg:
get the all params into loacal variables or you can use directly.
reg_no = params[:reg_no]
make = params[:make]
query = 'where '
if reg_no.present?
query = query+ "reg_no ilike #{reg_no} AND "
if make.present?
query = query + "make ilike #{make} AND "
use "=" is user enters "entire string" if it is partial use "ilike".
now you can use join and use the where condition.

Related

Ruby - ActiveRecord - Select one record per 'group' based on a specific column value

I have this table:
User
Name
Role
Mason
Engineer
Jackson
Engineer
Mason
Supervisor
Jackson
Supervisor
Graham
Engineer
Graham
Engineer
There can be exact duplicates (same Name/Role combination). Ignore comments about primary key.
I am writing a query that will give the distinct values from 'Name' column, with the corresponding 'Role'. To select the corresponding 'Role', if there is a 'Supervisor' role for a name, that record is returned. Otherwise, a record with the 'Engineer' role should be returned if it exists.
For the above table, the expected result is:
Name
Role
Mason
Supervisor
Jackson
Supervisor
Graham
Engineer
I tried ordering 'Role' in descending order, so that I can group by Name,Role and pick the first item - it will be a 'Supervisor' role if present, else 'Engineer' role - which matches my expecation.
I also tried doing User.select('DISTINCT ON (name) \*).order(Role: :desc) - I am not seeing this clause in the SQL query that gets executed.
Also, I tried another approach to get all valid Name, Role combinations and then process it offline iterating the result set and using if-else to decide which row to display.
However, I am interested in anything that is efficient and does not over do this handling.
I am new to Ruby and therefore reaching out.
If I wanted to do this in pure SQL, I would have to use GROUP BY.
SELECT Name, MAX(Role) FROM User GROUP BY Name
So one method would be to execute this SQL statement against the base connection.
ActiveRecord::Base.connection.execute("SELECT Name, MAX(Role) FROM User GROUP BY Name")
That would provide exactly the data you need, though it wouldn't be returned as ActiveRecord models. If you need those models then I would use find_by_sql and do an inner join to provide the records.
User.find_by_sql("SELECT User.* FROM User INNER JOIN (SELECT Name AS n, MAX(Role) AS r FROM User GROUP BY Name) U2 WHERE Name = U2.n AND Role = U2.r")
Unfortunately that would provide both records for Graham.

Clean and concise way to find active records that have the same id as another set of active records

I have a table called shoppers and another table called Users. I have a shopper_id which is the foreign key in the Shoppers table and refers to the primary key id in the Users table.
I ran a query called #shoppers = shoppers.where("some condition")
This allowed me to get a set of shoppers who satisfy the condition. Next I would like to select those Users who have the same id as the shopper_id as the individual objects in #shoppers.
I know I could do this by writing a loop, but I am wondering if ruby on rails allows me to write a Users.where condition that can help me obtain the subset of user objects with the same id as shopper_id arranged in ascending order by the name field in the Users table.
Any ideas?
Try this.
#shoppers = Shopper.where("some condition")
#users = User.where(id: #shoppers.collect(&:shopper_id)).order('name asc')

Ruby on Rails query limit in a range

I'm new to Ruby on Rails, and want to learn the basics of how a database works.
I created a table named Users with three columns, username, password, email, and I have three records inside. I made a query:
#user = Users.select(:username).limit(2)
which works.
Now I want to make a query like:
SELECT username FROM Users LIMIT 1,2
which means:
select 2 username column from table Users which starts at index 1
like a normal MySQL query.
I tried
#user = Users.select(:username).limit(1,2)
but it's not working. I don't actually know what to search for my situation. Tried limit query with range or limit from one to another index query but neither works.
I think I'm going to need it for printing out products with pages navigation.
I believe you need to use .offset(1)
#user = Users.select(:username).limit(2).offset(1)

Report using Rails ActiveRecord group by

I am trying to generate a report to screen of accounting transaction history. In most situations it is one display row per record in the AccountingTransaction table. But occasionally there are transactions that I wish to display to the end user as one transaction which are really, behind the scenes, two accounting transactions. This is caused by deferral of revenues and fund splitting since this app is a fund accounting app.
If I display all rows one by one, those double entries look odd to the user since the fund splitting and deferral is "behind the scenes". So I want to roll up all the related transactions into one display row on screen.
I have my query now using group by to group the related transactions
#history = AccountingTransaction.where("customer_id in (?) AND no_download <> 1", customers_in_account).group(:transaction_type_id, :reference_id).order(:created_at)
as I loop through I get the transactions grouped as I want but I am struggling with how to display the total sum of the 'credit' field for all records in the group. (It is only showing the credit for the first record of the group) If I add a .sum(:credit) to my query, of course, it returns the sums just as I want but not all the other data.
Is there a way for me to group these records like in my #history query and also get the sum of the credit field for each respective group?
* Addition *
What I really want is what the following SQL query would give me.
SELECT transaction_type_id, reference_id, sum(credit)
WHERE customer_id in (21,22,23,24) AND no_download <> 1
GROUP BY reference_id, transaction_type_id ORDER BY created_at
I'm not sure you can do "ORDER BY created_at" and not include it in the select fields, but here is an example.
#history = AccountingTransaction.
select([:reference_id, :transaction_type_id, :created_at]).
select(AccountingTransaction.arel_table[:credit].sum.as("credit_sum")).
where("customer_id in (?) AND no_download <> 1", customers_in_account).
group(:transaction_type_id, :reference_id).
order(:created_at)
To access the credit_sum you could do:
#history[0].attributes["credit_sum"]
I guess if you'd like, you could create a method:
def credit_sum
attributes["credit_sum"]
end
EDIT *
As stated in comments you can access the attribute directly:
#history[0].credit_sum

jpa 2 query to retrieve data using join table

I have table structure as follows
table user: iduser, firstName, lastName, username, email, dateJoined, dateOfBirth, password
table tag : idtag, tagName
table post: idpost, title, content, iduser, date, dateCreated
table post_tag : idpost, idtag :-join table for many to many relationship for tag and post
table user_tag : iduser, idtag :-join table for many to many relationship for user and tag
what i want is the names of the tags for a specific user using JPA query.
I also wanted to retrieve the post for the user and I could retrieve that using the following NamedQuery
SELECT p FROM Post p WHERE p.user = :user ORDER BY p.dateCreated DESC
using this, I was successfully able to retrieve posts for the user as Post and user are both entities and is a valid JPA query
But when I try to retrieve the tags for a specific just like I retrieved posts for user,
so I tried to write a join query something like this
SELECT t.tagName FROM tag t JOIN user_tag ut ON ut.idtag = t.idtag JOIN user u ON ut.iduser = u.iduser WHERE u.username = :username
but eclipse complaints for this query as user_tag is not the entity type. I am not able to formulate a join query using JPA QL which can retrieve tags for a user
Any help is highly appreciated.
I was able to formulate the query as follows
SELECT tag.tagName FROM Tag tag WHERE tag.users = :users
This was just like the query I used for Post and User
but I have another doubt that if we don't need to write a join query in this case, then in which scenarios JPA QL join queries are used?

Resources