官术网_书友最值得收藏!

How to do it...

Refactoring any code base is a process. For monoliths, there are a few techniques that can work quite well. In this example, we'll document the steps that can be taken to make refactoring a Ruby on Rails code base easy:

  1. Using the techniques described in previous recipes, identify business capabilities and bounded contexts within your application. Let's focus on the ability to upload pictures and videos. 

 

  1. Create a directory called app/services alongside controllers, models, and views. This directory will hold all of your service objects. Service objects are a pattern used in many Rails applications to factor out a conceptual service into a ruby object that does not inherit any Ruby on Rails functionality. This will make it easier to move the functionality encapsulated within a service object into a separate microservice. There is no one way to structure your service objects. I prefer to have each object represent a service, and move operations I want that service to be responsible for to that service object as methods. 
  2. Create a new file called attachments_service.rb under app/services and give it the following definition:
class AttachmentsService

def upload
# ...
end

def delete!
# ...
end

end
  1. Looking at the source code for the AttachmentsController#create method in the app/controllers/attachments_controller.rb file, it currently handles the responsibility for creating the Attachment instance and uploading the file data to the attachment store, which in this case is an Amazon S3 bucket. This is the functionality that we need to move to the newly created service object:
# POST /messages/:message_id/attachments
def create
message = Message.find_by!(params[:message_id], user_id:
current_user.id)
file = StorageBucket.files.create(
key: params[:file][:name],
body: StringIO.new(Base64.decode64(params[:file][:data]),
'rb'),
public: true
)
attachment = Attachment.new(attachment_params.merge!(message:
message))
attachment.url = file.public_url
attachment.file_name = params[:file][:name]
  attachment.save
json_response({ url: attachment.url }, :created)
end
  1. Open the newly created service object in the app/services/attachments_service.rb file and move the responsibility for uploading the file to the AttachmentsService#upload method:
class AttachmentsService

def upload(message_id, user_id, file_name, data, media_type)
message = Message.find_by!(message_id, user_id: user_id)
file = StorageBucket.files.create(
key: file_name,
body: StringIO.new(Base64.decode64(data), 'rb'),
public: true
)
Attachment.create(
media_type: media_type,
file_name: file_name,
url: file.public_url,
message: message
)
end

def delete!
end
end
  1. Now upload the AttachmentsController#create method in app/controllers/attachments_controller.rb to use the newly created AttachmentsService#upload method:
# POST /messages/:message_id/attachments
def create
service = AttachmentService.new
attachment = service.upload(params[:message_id], current_user.id,
params[:file][:name], params[:file][:data],
params[:media_type])
json_response({ url: attachment.url }, :created)
end
  1. Repeat this process for code in the AttachmentsController#destroy method, moving the responsibility to the new service object. When you're finished, no code in AttachmentsController should be interacting with the Attachments model directly; instead, it should be going through the AttachmentsService service object.

You've now isolated responsibility for the management of attachments to a single service class. This class should encapsulate all of the business logic that will eventually be moved to a new attachment service.

主站蜘蛛池模板: 阿坝| 鲁甸县| 库尔勒市| 兴隆县| 冀州市| 辽阳县| 普陀区| 镇雄县| 九龙县| 三台县| 马山县| 阿克苏市| 久治县| 马公市| 庄河市| 交城县| 嵊泗县| 互助| 临湘市| 荃湾区| 依安县| 桦南县| 泗水县| 和田县| 邹城市| 青铜峡市| 闽侯县| 巍山| 郁南县| 崇仁县| 镇巴县| 昌吉市| 资源县| 乌苏市| 万载县| 克什克腾旗| 临猗县| 永清县| 那坡县| 宜阳县| 安远县|