如何在 rails 模型中调用可重用代码?
How to call reusable code in rails model?
我的模型中有一个重复的方法,我想将这些代码放在一个地方,只是想将它访问到我的模型中。
我的模型有几个方法,例如:
class ProductionProductivity7 < ApplicationRecord
def self.import1(file)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
puts row.to_hash
product = find_by(id: row["id"]) || new
product.attributes = row.to_hash
product.save!
end
end
def self.search(search,compare)
if search == "All"
all.order(:id)
elsif compare == "Bihar vs District"
where("Districts = ? OR Districts = ?", search, "Bihar")
else
where(Districts: search)
end
end
结束
还有 3 个这样的方法,我想把这个代码块放到 helper 中,只想在模型中调用它。为此,我尝试将这些代码放入我的助手中。我使用以下方式调用它:
include ApplicationController.ProductionProductivity7sHelper
我将其包含在我的模型中,但出现此错误:
undefined method `ProductionProductivity7sHelper' for ApplicationController:Class
我的控制器代码是这样的:
def test
@ProductionProductivity7s = ProductionProductivity7.search(params[:search],compare)
a = ProductionProductivity7.query(@ProductionProductivity7s,params[:year],rain_fall_type,views,compare)
end
我在应用程序文件夹中添加了一个模块名称code.rb。
module Code
def search(search_scope,compare)
if search_scope == "All"
all.order(:id)
elsif compare == "Bihar vs District"
where("Districts = ? OR Districts = ?", search_scope, "Bihar")
else
where(Districts: search_scope)
end
end
end
我只想将我的模型的所有方法都写在某个地方,它可以是模块或帮助程序,而无需更改任何内容。有没有可能我只想在我的模型中使用这个代码块。
我正在要点文件中添加整个控制器代码和模型代码。请看一下 My controller and Model code link
我收到这个错误:
undefined method `search' for #<Class:0x00007ff115974fd8> Did you mean? search1
如何制作一个像这样的模块:
module Import1
def import1(file)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
puts row.to_hash
product = find_by(id: row["id"]) || new
product.attributes = row.to_hash
product.save!
end
end
def search(search_scope,compare)
if search_scope == "All"
all.order(:id)
elsif compare == "Bihar vs District"
where("Districts = ? OR Districts = ?", search_scope, "Bihar")
else
where(Districts: search_scope)
end
end
end
我想我会把它放在您的 app
文件夹中的某个地方,这样您就不会遇到自动加载问题。您 可以 将它放在您的根 app
文件夹中,但这对我来说似乎很乱。您 也可以 将它放在您的 models
文件夹中,但是您在同一个文件夹中有两种截然不同的东西,这对我来说也很乱。我想我会想创建一个新文件夹,例如 app/model_modules
或 app/shared_model_modules
,然后将您的 import_1.rb
文件放在那里。那么,这个文件是什么就一目了然了。
然后做:
class ProductionProductivity7 < ApplicationRecord
extend Import1
end
或者,使用服务而不是助手怎么样? IMO,它使正在发生的事情变得更加明确,而助手可以混淆代码所在的位置。
基本结构 BaseService
可能看起来像:
class BaseService
attr_accessor :args
class << self
def call(args=nil)
new(args).call
end
end # Class Methods
#=======================================================================
# Instance Methods
#=======================================================================
def initialize(args)
@args = args || {}
assign_args
end
private
def assign_args
args.each do |k,v|
class_eval do
attr_accessor k
end
send("#{k}=",v)
end
end
end
那么,您的文件导入服务可能类似于:
class ImportFileService < BaseService
def call
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
puts row.to_hash
product = klass.find_or_initialize_by(id: row["id"])
product.attributes = row.to_hash
product.save!
end
end
end
你会这样称呼你的服务:
ImportFileService.call(file: file, klass: ProductionProductivity7)
当然可以,您可以像这样创建一个模块吗:
module ProductionProductivity7sHelper
def import1(file) # notice I dropped 'self.'
...
end
...
end
然后在您的 class 中添加:
class ProductionProductivity7 < ApplicationRecord
extend ProductionProductivity7sHelper
...
end
这会将模块中定义的所有方法添加为 ProductionProductivity7 的 class 方法。注意:这假设您省略的方法也是 class 方法,即以 'self.'
开头
我的模型中有一个重复的方法,我想将这些代码放在一个地方,只是想将它访问到我的模型中。
我的模型有几个方法,例如:
class ProductionProductivity7 < ApplicationRecord
def self.import1(file)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
puts row.to_hash
product = find_by(id: row["id"]) || new
product.attributes = row.to_hash
product.save!
end
end
def self.search(search,compare)
if search == "All"
all.order(:id)
elsif compare == "Bihar vs District"
where("Districts = ? OR Districts = ?", search, "Bihar")
else
where(Districts: search)
end
end
结束
还有 3 个这样的方法,我想把这个代码块放到 helper 中,只想在模型中调用它。为此,我尝试将这些代码放入我的助手中。我使用以下方式调用它:
include ApplicationController.ProductionProductivity7sHelper
我将其包含在我的模型中,但出现此错误:
undefined method `ProductionProductivity7sHelper' for ApplicationController:Class
我的控制器代码是这样的:
def test
@ProductionProductivity7s = ProductionProductivity7.search(params[:search],compare)
a = ProductionProductivity7.query(@ProductionProductivity7s,params[:year],rain_fall_type,views,compare)
end
我在应用程序文件夹中添加了一个模块名称code.rb。
module Code
def search(search_scope,compare)
if search_scope == "All"
all.order(:id)
elsif compare == "Bihar vs District"
where("Districts = ? OR Districts = ?", search_scope, "Bihar")
else
where(Districts: search_scope)
end
end
end
我只想将我的模型的所有方法都写在某个地方,它可以是模块或帮助程序,而无需更改任何内容。有没有可能我只想在我的模型中使用这个代码块。
我正在要点文件中添加整个控制器代码和模型代码。请看一下 My controller and Model code link
我收到这个错误:
undefined method `search' for #<Class:0x00007ff115974fd8> Did you mean? search1
如何制作一个像这样的模块:
module Import1
def import1(file)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
puts row.to_hash
product = find_by(id: row["id"]) || new
product.attributes = row.to_hash
product.save!
end
end
def search(search_scope,compare)
if search_scope == "All"
all.order(:id)
elsif compare == "Bihar vs District"
where("Districts = ? OR Districts = ?", search_scope, "Bihar")
else
where(Districts: search_scope)
end
end
end
我想我会把它放在您的 app
文件夹中的某个地方,这样您就不会遇到自动加载问题。您 可以 将它放在您的根 app
文件夹中,但这对我来说似乎很乱。您 也可以 将它放在您的 models
文件夹中,但是您在同一个文件夹中有两种截然不同的东西,这对我来说也很乱。我想我会想创建一个新文件夹,例如 app/model_modules
或 app/shared_model_modules
,然后将您的 import_1.rb
文件放在那里。那么,这个文件是什么就一目了然了。
然后做:
class ProductionProductivity7 < ApplicationRecord
extend Import1
end
或者,使用服务而不是助手怎么样? IMO,它使正在发生的事情变得更加明确,而助手可以混淆代码所在的位置。
基本结构 BaseService
可能看起来像:
class BaseService
attr_accessor :args
class << self
def call(args=nil)
new(args).call
end
end # Class Methods
#=======================================================================
# Instance Methods
#=======================================================================
def initialize(args)
@args = args || {}
assign_args
end
private
def assign_args
args.each do |k,v|
class_eval do
attr_accessor k
end
send("#{k}=",v)
end
end
end
那么,您的文件导入服务可能类似于:
class ImportFileService < BaseService
def call
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
puts row.to_hash
product = klass.find_or_initialize_by(id: row["id"])
product.attributes = row.to_hash
product.save!
end
end
end
你会这样称呼你的服务:
ImportFileService.call(file: file, klass: ProductionProductivity7)
当然可以,您可以像这样创建一个模块吗:
module ProductionProductivity7sHelper
def import1(file) # notice I dropped 'self.'
...
end
...
end
然后在您的 class 中添加:
class ProductionProductivity7 < ApplicationRecord
extend ProductionProductivity7sHelper
...
end
这会将模块中定义的所有方法添加为 ProductionProductivity7 的 class 方法。注意:这假设您省略的方法也是 class 方法,即以 'self.'
开头