Ransack и find_by_sql [дубликаты]

На это было много ответов, но я дам свое мнение по этому вопросу в любом случае. Причина этого нечетного поведения, как говорилось ранее, исходит от POSIX C time.h, где указаны месяцы, когда они хранятся в int с диапазоном 0-11. Чтобы объяснить, почему, посмотрите на это так: годы и дни считаются числами на разговорном языке, но у месяцев есть свои имена. Поэтому, поскольку январь является первым месяцем, он будет сохранен как смещение 0, первый элемент массива. monthname[JANUARY] будет "January". Первый месяц в году - это элемент массива первого месяца.

Число дней, с другой стороны, поскольку у них нет имен, сохранение их в int как 0-30 будет путать, добавьте много day+1 инструкций для вывода и, конечно же, склонны к большому количеству ошибок.

Как говорится, непоследовательность запутывает, особенно в javascript (который также унаследовал эту «функцию») язык сценариев, где это должно быть абстрагировано далеко от langague.

TL; DR: Поскольку в месяцах имена и дни месяца этого не делают.

0
задан Massimiliano 19 March 2019 в 16:12
поделиться

1 ответ

Я бы рекомендовал избегать find_by_sql и конвертировать ваш запрос в более правильный запрос ActiveRecord

В Rails 5+ Вы можете попробовать следующее:

class Patient < ApplicationRecord
   scope :basic_info, -> { 
        self.left_joins(hospitalizations: :surgery)
           .distinct
           .select("first_name, 
                    last_name, 
                    gender,  
                    MAX(surgeries.surgery_date) as most_recent_surgery")
           .group("first_name, last_name, gender")
   }
end

Это обеспечит тот же SQL, что и ваш find_by_sql, но вернет ActiveRecord::Relation, а не ActiveRecord::Result. Это должно позволить связать Ransack с ответом следующим образом:

def index
  @p = Patient.basic_info.ransack(params[:q])
  @patients = @p.result.page(params[:page])

end

Если вы используете Rails меньше 5 , тогда он становится немного более запутанным, но следующее все равно предоставит то же самое

class Patient < ApplicationRecord
   scope :basic_info, -> { 
        patient_table = Patient.arel_table
        hospitalizations_table = Hospitaliztion.arel_table
        surgeries_table = Surgery.arel_table
        patient_join = patient_table.join(hospitalizations_table,Arel::Nodes::OuterJoin).on(
            hospitalizations_table[:patient_id].eq(patient_table[:id])
        ).join(surgeries_table, Arel::Nodes::OuterJoin).on(
          surgeries_table[:hospitalization_id].eq(hospitalizations_table[:id])
        )  
        self.joins(patient_join.join_sources)
           .select("first_name, 
                    last_name, 
                    gender,  
                    MAX(surgeries.surgery_date) as most_recent_surgery")
           .group("first_name, last_name, gender")
   }
end
0
ответ дан engineersmnky 19 March 2019 в 16:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: