我的Rails 5应用程序的控制器开始变得拥挤,所以我正在考虑尽可能多地移动到服务类。这适用于大多数业务逻辑,但我似乎无法将任何实例变量移出方法。我想要做的是遵循这种模式:
# users_controller.rb
class UsersController < ApplicationController
def show
UserService.new.set_user_detail_variables(params[:id])
respond_to do |format|
format.html
format.json { render json: @user }
end
end
end
# user_service.rb
class UserService
def set_user_detail_variables(user_id)
@user = User.find(user_id)
@cars = Car.where(brand: 'Volvo')
end
end
是否可以将实例变量移出控制器?
答案 0 :(得分:1)
如果你想在一个单独的方法中做一些计算并在那里分配一些实例变量,然后在你的视图中使用它们,你可以将这些方法移动到mixin并在控制器中包含mixin。
# mixins/user_helper.rb
module UserHelper
def set_user_detail_variables(user_id)
@user = User.includes(:comments, :addresses, :posts).find(user_id)
@user_comments = @user.comments
@user_addresses = @user.addresses
@user_posts = @user.posts
end
end
# controllers/users_controller.rb
class UsersController < ApplicationController
include UserHelper
def show
set_user_detail_variables(params[:id])
respond_to do |format|
format.html
format.json { render json: @user }
end
end
end
这样你的控制器就不会变得冗长,而且你也可以使用你的变量。
答案 1 :(得分:1)
根据您更新的问题更新
我认为您必须在控制器操作中至少有一个实例变量来呈现其数据或将其作为json
发送。并且服务对象不是那样做的事情。旨在执行单个巨大或复杂操作的服务对象。
您可以做的是使用Presenter对象(Presenter模式作为Rails社区看到它)。 Rails中的这种模式对于隐藏&#34;单个实例中的几个实例变量。因此,将实例变量放在单个Presenter变量中。然后将演示者传递给视图或将其数据呈现为json
。
示例强>
在:
class UsersController < ApplicationController
def show
@user = User.find(user_id)
@cars = Car.where(brand: 'Volvo')
respond_to do |format|
format.html
format.json { render json: @user, @car }
end
end
end
后:
class UsersController < ApplicationController
def show
user = User.find(user_id)
cars = Car.where(brand: 'Volvo')
@show_presenter = ShowPresenter.new(user, cars)
respond_to do |format|
format.html
format.json { render json: @show_presenter }
end
end
end
class ShowPresenter
def initialize(user, cars)
@user = user
@cars = cars
end
end