#sql #ruby-on-rails #ruby #activerecord #rails-postgresql
#sql #ruby-on-rails #ruby #activerecord #rails-postgresql
Вопрос:
Такое ощущение, что на это уже должен был быть дан ответ, но мой поиск foo меня подводит.
Работая в Rails 3.2, предположим, что у нас есть две таблицы БД, которые имеют достаточно идентичные столбцы для столбцов, о которых мы заботимся в этом выборе, вот так:
create_table "current_employees" do |t|
t.string "first_name"
t.string "middle_name"
t.string "last_name"
. . . more columns
end
create_table "ex_employees" do |t|
t.string "first_name"
t.string "middle_name"
t.string "last_name"
. . . more columns
end
Да, выдуманный пример: просто пойдите с ним сейчас.
Когда отдел кадров хочет найти текущего или бывшего сотрудника, они не хотят проводить различие между двумя таблицами: им нужны результаты, которые могут быть в любой таблице.
Как мне настроить мои модели, контроллеры и т.д., Чтобы получать результаты из любой таблицы?
Например, Джек Джексон находится в current_employees
таблице, а Джек О’Лантерн — в ex_employees
таблице. При выполнении поиска по «Jack» в таблице результатов должно быть две строки: одна для Джека Джексона, а другая для Джека О’Лантерна.
Обновлено для указания Rails 3.2.
Комментарии:
1. Это:
CurrentEmployees.joins("Full outer join ex_employees").where("first_name like '?%'", "Jack")
должно сработать, я думаю
Ответ №1:
Если вам не нужно вносить изменения в базу данных, вы могли бы использовать представление, которое выполняет объединение обеих таблиц и создает модель из этого представления
class Employee < ActiveRecord::Base
self.table_name = 'Employeeview'
self.primary_key = 'employee_id'
protected
def readonly?
true
end
end
Ответ №2:
Вам придется выполнить два разных запроса и получить все результаты в одном массиве
search_results = []
search_results = CurrentEmployee.where("name like '%Jack%'").all
search_results = ExEmployee.where("name like '%Jack%'").all
И теперь отобразите все записи из массива в представлении
Ответ №3:
Не зная, какую версию Rails вы используете, вы можете использовать Arel
для генерации SQL-запроса для внешнего соединения, например:
Arel::Table.new(:current_employees).join(Arel::Table.new(:ex_employees), Arel::Nodes::OuterJoin).on(Arel::Table.new(:current_employees)[:first_name].eq(Arel::Table.new(:ex_employees)[:first_name]))
которые генерируют следующий SQL-запрос:
irb(main):001:0> Arel::Table.new(:current_employees).join(Arel::Table.new(:ex_employees), Arel::Nodes::OuterJoin).on(Arel::Table.new(:current_employees)[:first_name].eq(Arel::Table.new(:ex_employees)[:first_name])).to_sql
=> "SELECT FROM "current_employees" LEFT OUTER JOIN "ex_employees" ON "current_employees"."first_name" = "ex_employees"."first_name""
Комментарии:
1. Хороший момент. Обновляю вопрос, чтобы указать, что я на Rails 3.19.