How to clean dirty views and controllers in Rails?

My application has this code:

if @document.template.name == "Newsletter" ... end 

I understand that this is bad and ugly code. I'm not sure what alternatives exist for such code. Are there any recommendations for this? I hope so. Hooray!

Controller Code Example

In this example controller code, it sends an image to Twitter if the name is "Newsletter" . I know that this is messy, and that a lot of code needs to be ported to the model. I'm more concerned about the conditional.

 if @document.template.name == "Newsletter" source = Magick::Image.read(@document.component.image_newsletter.path).first overlay = Magick::Image.read(@document.user.logo.path).first.resize_to_fit(source.columns) rec = Magick::Draw.new rec.stroke = "##{@document.user.colour1}" rec.fill = "##{@document.user.colour1}" rec.rectangle 0, 0, source.rows, 5 lank = source.extent(source.columns, source.rows+overlay.rows, 0 ,0) combo = lank.composite(overlay, Magick::SouthGravity, 0, 0, Magick::OverCompositeOp) rec.draw(combo) client.update_with_media("#{@document.title}: #{@document.remove_html(@document.components.first.body[0..100])}...", open(combo.to_blob)) else client.update("#{@document.title}: #{@document.remove_html(@document.components.first.body[0..100])}... http://domain.com#{share_path(@document.user.ftp, @document)}") end 
+6
source share
2 answers

The only alternative I can think of now is to move the template-specific code to the Template model, divided into separate methods that follow a specific naming convention.

For example, your methods may follow the process_x convention, where x is the name of the template. In this case, the code you posted for the "newsletter" will have the process_newsletter method.

I would also create one entry point, call her process in the same model, which is responsible for delegating to one of these methods:

 class Template < ActiveRecord::Base ... other model code def process # this is the method to be called from the controller method_name = "process_#{self.name}" # the name of the method to be called send method_name # call a method by this name end def process_newsletter # your newsletter code already posted end def process_article # another example for illustration purposes # article specific code end end 

This not only eliminates the need to check the template name, but also helps to further separate your code and move any elements related to a particular model from the controller.

+2
source

Presenter Rescue Template

application / helpers / application_helper.rb

This will give you convenient access to a presenter instance anywhere in any of your presentations.

For example, if you use present @document , it will create an instance of DocumentPresenter .

 module ApplicationHelper def present object, klass = nil klass ||= "#{object.class}Presenter".constantize presenter = klass.new object, self yield presenter if block_given? presenter end end 

To override the presenter used, you can do present @document, MyPresenter


application / Presenters / document.rb

Your actual speaker. Create as many instance methods as you want and save all the presentation logic here. You have access to all helper viewing methods via @template

 class DocumentPresenter def initialize document, template @document = document @template = template end def name if @document.template.name == "Newsletter" # for example ... @template.link_to 'Newsletter', @template.document_index_path end end def description @template.content_tag :p, @document.description, class: "description" end end 

application / views / document / show.html.erb

 <% present @document do |document_presenter| %> <div id="document"> <%= document_presenter.description %> <%= document_presenter.name %> </div> <% end %> 

Result

 <div id="document"> <p class="description"> lorem ipsum </p> <a href="/newsletters">Newsletters</a> </div> 

You can learn more about the presenter template, as Ryan Bates did in his RailsCast episode “Presenters from Scratches

+5
source

Source: https://habr.com/ru/post/957637/


All Articles