这是您的基础:
# view
<p>
  <%= text_field_tag :search, params[:search] %>
  <%= select_tag :search_column, options_for_select(Truck.column_names, params[:search_column]) %>
  <%= submit_tag "Search", :name => nil %>
</p>
# controller
def index
  @trucks = Truck.search(params[:search], params[:search_column])
# model
def self.search(keyword, column_name)
  if self.column_names.include?(column_name.to_s)
    where("trucks.#{column_name} LIKE ?", "%#{keyword}%")
  else
    scoped
  end
end
您可以在此处进行多项改进:
- 将翻译添加到select_field_tag以查看翻译后的属性
- 添加一个类方法,该方法将仅返回您希望“可搜索”的列
- 使用 ActiveRecord 的方法sanitize来确保column_name是安全的
如果您需要,我可以帮助您进行改进。
返回可搜索列的类方法:
在这里我们有一个选择,我们是否应该得到所有的列并去掉其中的一些?还是我们应该只选择我们想要的?第一个选项意味着如果您向模型添加一个属性,它将默认添加到选项中,除非您将其取消。第二种选择会发生相反的情况:
# model
# This method should return the columns defined in the `wanted_columns` array
def self.searchable_columns
  wanted_columns = ['name', 'description', 'etc' ]
  self.column_names.select{ |column| wanted_column.include?(column) }
end
# This method will return the columns NOT IN the `unwanted_columns` array
def self.searchable_columns
  unwanted_column = ['id', 'created_at', 'updated_at']
  self.column_names.reject{ |column| unwanted_column.include?(column) }
end
# view
<%= select_tag :search_column, options_for_select(Truck.searchable_columns, params[:search_column]) %>
显示翻译而不是列名
# model
# This method return an array of arrays formatted like following:
# [ ['Name', 'name'], ['Truck Number', 'truck_no'] ]
def self.translated_searchable_columns
  columns = self.searchable_columns
  result = columns.map{ |column| [Truck.human_attribute_name(column.to_sym), column] }
  result
end
# view
<%= select_tag :search_column, options_for_select(Truck.translated_searchable_columns, params[:search_column]) %>