我试图概括一些将由多个模型/视图/控制器使用的方法,但我没有运气。这是原始代码,只适用于1套名为Trucks。
查看
<h2>Trucks</h2>
<%= form_tag trucks_path, :method => 'get' do %>
<%= hidden_field_tag :direction, params[:direction] %>
<%= hidden_field_tag :sort, params[:sort] %>
<p>
Search:
<%= text_field_tag :search %>
by
<%= select_tag :search_column, options_for_select(Truck.translated_searchable_columns(['attribute1']), params[:search_column]) %>
<%= submit_tag "Search" %>
</p>
<% end %>
<!-- Display code goes here, but im not showing since its just a table -->
控制器
def index
@trucks = Truck.search(params[:search], params[:search_column]).order(sort_column(Truck, "truck_no") + " " + sort_direction)
respond_to do |format|
format.html # index.html.erb
format.json { render json: @trucks }
end
end
模型
class Truck < ActiveRecord::Base
attr_accessible :attribute1, :attribute2, :attribute3
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
def self.searchable_columns(unwanted_columns)
self.column_names.reject{ |column| unwanted_columns.include?(column) }
end
def self.translated_searchable_columns(unwanted_columns)
columns = self.searchable_columns(unwanted_columns)
result = columns.map{ |column| [Truck.human_attribute_name(column.to_sym), column] }
result
end
end
所有这一切顺利进行,现在我无法弄清楚我的生活如何将这些方法移动到lib并让它们一般化,以便让我们说预告片能够以相同的方法调用并传入其中信息并取得同样的结果。我想尽可能使代码DRY。谁能解释一下我需要做些什么才能实现这个目标? lib如何访问数据库?
答案 0 :(得分:3)
您正在寻找的概念被称为“关注”。 Rails有一个便利模块,用于实现名为ActiveSupport::Concern的问题。以下是您可以提取模型方法的方法:
module Searchable
extend ActiveSupport::Concern
module ClassMethods
def search(keyword, column_name)
if column_names.include?(column_name.to_s)
where("#{table_name}.#{column_name} LIKE ?", "%#{keyword}%")
else
scoped
end
end
def searchable_columns(unwanted_columns)
column_names.reject{ |column| unwanted_columns.include?(column) }
end
def translated_searchable_columns(unwanted_columns)
columns = searchable_columns(unwanted_columns)
columns.map{ |column| [human_attribute_name(column.to_sym), column] }
end
end
end
然后在你的模型中:
class Truck < ActiveRecord::Base
include Searchable
attr_accessible :attribute1, :attribute2, :attribute3
end
至于你应该在哪里存储Searchable
模块,这取决于你 - 它必须是config.autoload_paths
中包含的某个地方,就像模型或控制器一样。 Rails 4引入了一个约定,模型关注点存储在app/models/concerns
中,控制器问题存储在app/controllers/concerns
中,但除了默认自动加载之外,这些位置没有什么特别之处。