Я бы рекомендовал избегать 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
Необходимо, вероятно, использовать select
вместо этого.
Как так:
f.select(:category_id, @categories.collect {|p| [ p.name, p.id ] } + [ [ 'Or create a new one', 'new' ] ], {:include_blank => 'Please select a category'})
Удачи!
Короткий ответ: нет.
Длинный ответ: Несомненно, но необходимо быть лукавыми.
Создайте класс как так:
class New_option_placeholder
def id
"new"
end
def name
"...or create a new one"
end
end
Вместо передачи @categories
, передача @categories+New_option_placeholder.new
(Как обозначено комментариями) при поиске чего-то более краткого, Вы могли require "ostruct"
и затем передача @categories + [OpenStruct.new(:id => 'new',:name => '...or create a new one')]
выполнять по существу то же это.
Согласен с коротким ответом No и длинным ответом " Be Crafty ", но вот что я только что сделал, который я думаю проще, чем любое из этих двух решений и сработал для меня:
Оберните следующую строку внутри тегов erb i. <%=
и %>
:
f.collection_select :advertisement_group_id, AdvertisementGroup.find(:all, :order => "name DESC") << AdvertisementGroup.new(:name => "New Group"), :id, :name, :include_blank => true
Просто создайте новый объект с .new
и передайте в него любой текст, который вы хотите отобразить вместе с :include_blank => true
.