I have an application that has a table Doctors with a name field. The users can put any version of the name in there they want. I'm trying to sort the records based on last name(last word in the string) before I display them in the index view.
I came up with a query that works in the console but gets an error when running it in the controller.
The query is as follows:
current_user.doctors.select("doctors.*, split_part(doctors.name, ' ', -1) AS lastname").order('lastname ASC')
My table migration:
class CreateDoctors < ActiveRecord::Migration[7.1]
def change
create_table :doctors do |t|
t.string :name
t.string :field
t.string :address
t.string :phone
t.string :fax
t.string :website
t.string :portal
t.binary :active, default: true
t.string :group
t.timestamps
end
end
end
My controller code:
def index
@doctors =
current_user.doctors.select("doctors.*, split_part(doctors.name, ' ', -1) AS lastname").order('lastname ASC')
end
And my view code:
<%= turbo_frame_tag Doctor.new %>
<%= turbo_frame_tag "doctors" do %>
<% @doctors.each do |doctor| %>
<%= render 'doctor_index', doctor: doctor %>
<% end %>
<% end %>
The error I get is the following:
17:16:53 web.1 | Started GET "/doctors" for ::1 at 2024-03-16 17:16:53 -0600
17:16:53 web.1 | ActiveRecord::SchemaMigration Load (1.0ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
17:16:53 web.1 | Processing by DoctorsController#index as HTML
17:16:53 web.1 | User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 2], ["LIMIT", 1]]
17:16:53 web.1 | Rendering layout layouts/application.html.erb
17:16:53 web.1 | Rendering doctors/index.html.erb within layouts/application
17:16:53 web.1 | Rendered shared/_nav-tabs.erb (Duration: 1.2ms | Allocations: 482)
17:16:53 web.1 | Doctor Count (21.8ms) SELECT COUNT(doctors.*, split_part(doctors.name, ' ', -1) AS lastname) FROM "doctors" WHERE "doctors"."user_id" = $1 [["user_id", 2]]
17:16:53 web.1 | ↳ app/views/doctors/index.html.erb:12
17:16:53 web.1 | Rendered doctors/index.html.erb within layouts/application (Duration: 83.8ms | Allocations: 17358)
17:16:53 web.1 | Rendered layout layouts/application.html.erb (Duration: 84.2ms | Allocations: 17477)
17:16:53 web.1 | Completed 500 Internal Server Error in 254ms (ActiveRecord: 42.9ms | Allocations: 54020)
17:16:53 web.1 |
17:16:53 web.1 |
17:16:53 web.1 |
17:16:53 web.1 | ActionView::Template::Error (PG::SyntaxError: ERROR: syntax error at or near "AS"
17:16:53 web.1 | LINE 1: ...OUNT(doctors.*, split_part(doctors.name, ' ', -1) AS lastnam...
17:16:53 web.1 | ^
17:16:53 web.1 | ):
17:16:53 web.1 | 9: </div>
17:16:53 web.1 | 10: <%= turbo_frame_tag Doctor.new %>
17:16:53 web.1 | 11: <%= turbo_frame_tag "doctors" do %>
17:16:53 web.1 | 12: <% if @doctors.count != 0 %>
17:16:53 web.1 | 13: <% @doctors.each do |doctor| %>
17:16:53 web.1 | 14: <%= render 'doctor_index', doctor: doctor %>
17:16:53 web.1 | 15: <% end %>
17:16:53 web.1 |
Running it in the console produces the results I'm looking for, which is a list of doctors records ordered by last name.
I'm sure it's a conversion problem from the Rails query to the psql query but I can't figure out how to rewrite it so that it works the way I want. I am confused why it works in the console but not the controller though.