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

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.

主站蜘蛛池模板: 新乐市| 永泰县| 漳平市| 西林县| 镇原县| 泊头市| 韶山市| 绥阳县| 长宁区| 宜城市| 柳州市| 永寿县| 嘉义县| 皋兰县| 乐都县| 台安县| 偃师市| 昌乐县| 彭泽县| 叙永县| 开平市| 正阳县| 微博| 宁晋县| 中超| 丹寨县| 义马市| 彭州市| 南皮县| 武城县| 隆尧县| 十堰市| 板桥市| 田林县| 保山市| 扬州市| 富平县| 汶川县| 中西区| 荥阳市| 若尔盖县|