oka*_*56k 6 ruby ruby-on-rails ruby-on-rails-3
我在我的应用程序中有很多这样的代码:
if @document.template.name == "Newsletter"
...
end
Run Code Online (Sandbox Code Playgroud)
我意识到的是糟糕而丑陋的代码.我不确定这种代码有哪些替代方案.它有什么最佳实践吗?希望如此.干杯!
样本控制器代码
在此控制器代码示例中,如果名称是,则将图像发布到Twitter "Newsletter"
.我知道它很乱,而且很多代码都应该移到模型中.我更关心有条件的.
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
Run Code Online (Sandbox Code Playgroud)
应用程序/佣工/ application_helper.rb
这将使您可以方便地在任何视图中的任何位置实例化演示者.
例如,如果你使用present @document
它将实例化一个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
Run Code Online (Sandbox Code Playgroud)
要覆盖使用的演示者,您可以这样做 present @document, MyPresenter
应用程序/主持人/ document.rb
你真正的主持人.根据需要创建尽可能多的实例方法,并将所有视图逻辑保留在此处.您可以访问所有视图助手方法@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
Run Code Online (Sandbox Code Playgroud)
应用程序/视图/文件/ show.html.erb
<% present @document do |document_presenter| %>
<div id="document">
<%= document_presenter.description %>
<%= document_presenter.name %>
</div>
<% end %>
Run Code Online (Sandbox Code Playgroud)
结果
<div id="document">
<p class="description">
lorem ipsum
</p>
<a href="/newsletters">Newsletters</a>
</div>
Run Code Online (Sandbox Code Playgroud)
您可以在Ryan Bates的RailsCast剧集"Scratch Presenters"中了解有关Presenter模式的更多信息.
我目前能想到的唯一替代方案是将模板特定的代码移到模型中Template
,分成遵循特定命名约定的各个方法。
例如,您的方法可以遵循约定process_x
,其中x
是模板的名称。在这种情况下,您为“新闻通讯”发布的代码将位于名为 的方法中process_newsletter
。
我还将process
在同一模型中创建一个单一入口点(我们称之为 ),它负责委托给这些方法之一,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
这不仅消除了模板名称检查的需要,而且还有助于进一步分离代码,并将任何特定于模型的内容从控制器中移走。
归档时间: |
|
查看次数: |
937 次 |
最近记录: |