2

完成以下任务的最有效方法是什么:从下拉列表中获取一个值并将其与搜索功能一起传递给模型。

这是用于搜索的html:

<p>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag "Search", :name => nil %>
</p>

这是控制器中的代码:

def index
  @trucks = Truck.search(params[:search])

  respond_to do |format|
  format.html # index.html.erb
  format.json { render json: @trucks }
end

结尾

这是模型

def self.search(search)
  if search
    where('truck_no LIKE ?', "%#{search}%")
  else
    scoped

结尾

在我的模型中'truck_no LIKE ?'

我希望它成为column_name + ' LIKE ?'我通过方法参数传入列名的位置。我将如何在 html 中设置我的下拉列表并将其一直传递给控制器​​?实现这一目标的最佳方法是什么?

编辑:忘了提,下拉应该显示卡车号码之类的东西,但传入值 truck_no

4

1 回答 1

5

这是您的基础

# 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]) %>
于 2013-08-09T13:43:47.863 回答