我最近遇到了一些使用方法调用的代码,该方法调用由格式组成,但object.(arg1, arg2) 没有很好地解释它是如何工作的.请参阅以下示例代码:
class TestServiceObject
def call
'method'
end
end
TestServiceObject.new.()
# => 'method'
Run Code Online (Sandbox Code Playgroud)
这种速记的术语是什么?
我们正在构建具有非数据库组件的模型的应用程序.我们很想知道其他人在rails社区中正在做些什么来解决这个问题.
我们正在努力把它们放在哪里.
我们应该:
app/models/domain
Run Code Online (Sandbox Code Playgroud)
要么
app/domain/models
Run Code Online (Sandbox Code Playgroud)
也许
app/models # Business Models
app/models/ar # Active Record Models
Run Code Online (Sandbox Code Playgroud)
也许
app/models/domain/ # Business Models
app/models/domain/ar # Active Record Models
Run Code Online (Sandbox Code Playgroud)
部分原因是我们正在努力解决与铁路标准的接近程度以及创建一个对我们需要的产品有利的结构.
如果我们将对象视为服务对象,我们就可以
app/models/service-object
Run Code Online (Sandbox Code Playgroud)
和
app/models/ # For plain active record
Run Code Online (Sandbox Code Playgroud)
下去的另一条路线是app内没有东西,例如
/service_objects
Run Code Online (Sandbox Code Playgroud)
代替
/app/models/service_objects
Run Code Online (Sandbox Code Playgroud)
据推测,如果我们想要通过rails应用程序访问,我们最好使用app /以便利用约定优于配置.
我想将服务对象添加到我的控制器中。是否有机会在此服务对象中包含 Flash 消息?
user_stocks_controller
class UserStocksController < ApplicationController
def create
@user_stock = UserStocksCreator.new(current_user, params).call
redirect_to my_portfolio_path
end
end
Run Code Online (Sandbox Code Playgroud)
服务对象user_stocks_creator
class UserStocksCreator
def initialize(current_user, params)
@current_user = current_user
@params = params[:stock_ticker]
end
def call
stock = Stock.find_by_ticker(params)
if stock.blank?
stock = Stock.new_from_lookup(params)
stock.save
end
@user_stock = UserStock.create(user: current_user, stock: stock)
flash[:success] = "Stock #{@user_stock.stock.name} was successfully added to portfolio"
end
private
attr_accessor :current_user, :params
end
Run Code Online (Sandbox Code Playgroud)
使用此代码,我有一个错误:
未定义的局部变量或方法`flash'
我刚刚在控制器和模型之间写了一个服务对象来"标记出勤",所以现在我有一个控制器动作对象,如下所示:
class BookingAttendancesController
def mark_attending
attendance_marker = BookingAttendances::AttendanceMarkerService.new params, current_entity
result = attendance_marker.call
# flash msg etc
end
end
Run Code Online (Sandbox Code Playgroud)
和服务对象(当前实现):
# app/services/booking_attendances/attendance_marker_service.rb
module BookingAttendances
class AttendanceMarkerService
def initialize(params, entity)
# ...
end
def call
# ...
end
# ...
end
end
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想在控制器类中命名服务对象,但rails希望该文件定义服务类,而不是嵌套在控制器中的服务类.
该模块的名称可用,但我不确定是否有这样的约定.总的来说,我觉得最困扰我的是我真的想在控制器中定义该类,但是在一个单独的文件中(可能有嵌套).我可以将模块包含在控制器中,但这不是我的观点.在rails中是否存在命名空间服务对象的最佳实践?
我想在我的控制器中添加服务对象。但是销毁操作似乎无法正常工作-基本上它不会删除任何内容,只是重定向到没有Flash消息的页面。
user_stock_destroyer.rb
class UserStocksDestroyer
def initialize(current_user, params, flash)
@current_user = current_user
@params = params[:id]
@flash = flash
end
def call
stock = Stock.find(params)
@user_stock = UserStock.where(user_id: current_user.id, stock_id: stock.id).first
@user_stock.destroy!
flash[:notice] = 'Stock successfully removed'
end
private
attr_reader :current_user, :params, :flash
end
Run Code Online (Sandbox Code Playgroud)
user_stocks_controller.rb
class UserStocksController < ApplicationController
def destroy
UserStocksDestroyer.new(current_user, params, flash)
redirect_to my_portfolio_path
end
end
Run Code Online (Sandbox Code Playgroud) 我正在尝试将一些业务逻辑从一个控制器中移出,StoreController并移到一个新的Store::CreateService服务对象中。最近了解了服务,似乎并没有很多实现这些服务的既定模式。我在尝试调用受保护的方法时遇到错误。我显然可以将逻辑从那些受保护的方法直接移到其中,execute但是我的理解是,这对Rails应该没问题。
undefined local variable or method `find_and_set_account_id' for #<Store::CreateService:0x00007f832f8928f8>
Run Code Online (Sandbox Code Playgroud)
这是服务对象
module Store
class CreateService < BaseService
def initialize(user, params)
@current_user, @params = user, params.dup
end
def execute
@store = Store.new(params)
@store.creator = current_user
find_and_set_account_id
if @store.save
# Make sure that the user is allowed to use the specified visibility level
@store.members.create(
role: "owner",
user: current_user
)
end
after_create_actions if @store.persisted?
@store
end
end
protected
def after_create_actions
event_service.create_store(@store, current_user)
end
def find_and_set_account_id
loop do
@store.account_id …Run Code Online (Sandbox Code Playgroud)