我正在开发一个带有单独的Rails / Angular前端代码库的Rails API后端。 Rails API的响应必须以某种方式构造,以匹配前端Flash消息。 A(n)(稍微简化)示例控制器响应是
render json: {status: "Unauthorized", code: "AUTH.UNAUTHORIZED", fallback_msg: "Unauthorized request"}
所以基本上所有的控制器都充满了这个,有时当一个方法有5个可能的响应时(例如:如果用户重置他们的电子邮件,响应可能是无效的密码,无效的电子邮件,电子邮件已经注册等)。同事建议将这些方法抽象出模型,因此模型是回复这些消息的响应,然后控制器就可以了
def ctrl_method
user = User.update(password: password)
render json: user, status(user)
end
(其中status是另一种根据对象的status属性提供HTTP状态代码的方法)
我的问题是这是最佳做法吗?我理解Rails MVC并觉得发送json消息的责任属于控制器而不是模型。
答案 0 :(得分:1)
我说你们都是对的。控制器应该负责发送消息,和方法应该被抽象出来 - 只是没有进入模型,更像是一个住在/lib
的类。
这也应该使测试更容易。
答案 1 :(得分:0)
在不知道任何细节的情况下,我会考虑利用问题来处理这些状态。这样可以封装业务逻辑,而不会使模型混乱。你可以拥有
module Concerns
module Statuses
def deal_with_show
# business logic goes here to generate the status
end
def deal_with_index
# business logic goes here to generate the status
end
def deal_with_create
# business logic goes here to generate the status
end
def default_status
# set a default status here
end
end
end
然后在控制器中
class MyController < ApplicationController
include Concerns::Statuses
def index
render json: deal_with_index
end
end
当然,关注状态的细分是任意的。它可以被处理但是有意义:通过方法,动词或其他一些区别。
这是concerns上的一点点。
答案 2 :(得分:0)
如果您想处理ActiveRecord错误,我认为您使用errors.full_messages
并对此类错误使用相同的代码和状态(状态:'禁止',代码:'')。
请注意,您应该在区域设置文件see guide中自定义消息。但如果您想用不同的语言翻译您的应用程序,这将非常有用。
可以从控制器和动作推断成功消息(见下文)。
class ApplicationController < ActionController::Base
...
def render_errors(object)
render json: {status: 'Forbidden', code: 'WRONG_DATA', fallback_msg: object.errors.full_messages.join(", ")}
end
def render_success(message = nil)
message ||= I18n.t("#{self.controller_name}.message.#{self.action_name}"
render json: {status: 'OK', code: 'OK', fallback_msg: message}
end
end
class SomeController < ApplicationController
def update
if @some.update(params)
render_success
else
render_errors(@some)
end
end
end