【问题标题】:rails4 using helper/service and where to put itrails4 使用助手/服务以及放置它的位置
【发布时间】:2016-06-11 13:15:06
【问题描述】:

我创建了这个类,用于根据产品属性的长度组装文本以在 twitter 上共享。

我的问题:

  • 这是解决问题的好方法吗?如果不是这个,那又如何? (我应该把类和方法放在哪里,如何调用它等等)
  • 如果这是好的方法,那么应该改变什么?例如,我觉得 def twitter_share_text 不应该在 product.rb 中。

show.html.erb

<a class="twitter-share" data-behavior="twitter-share" 
                         data-twittertext="<%= @product.twitter_share_text %>" 
                         data-twitterurl="<%= product_url(@product) %>" 
                         data-twitteranchor>
  <i class="fa fa-lg fa-twitter"></i>
</a>

产品.rb

def twitter_share_text
  TwitterProductShare.new(self).return_text
end

app/services/twitter_product_share.rb

class TwitterProductShare
  URL_LENGTH = 23 #defined by twitter API
  SPACE_LENGTH = 1
  TWITTER_MAX = 140
  attr_reader :name, :oneliner

  def initialize(product)
    @name = product.name
    @oneliner = product.oneliner
  end

  def return_text
    if full_length <= TWITTER_MAX
      return basic_text
    else
      return basic_text[0...-(difference + text_end.length)] + text_end
    end
  end

  private

    def basic_text
      "#{name}: #{oneliner}"
    end

    def difference
      full_length - TWITTER_MAX
    end

    def full_length
      basic_text.length + SPACE_LENGTH + URL_LENGTH
    end

    def text_end
      "..."
    end
end

【问题讨论】:

    标签: ruby-on-rails ruby helper service-object


    【解决方案1】:

    我认为这样的代码属于视图助手:

    # in app/helpers/product_helper.rb
    def twitter_share_link(product)
      data = {
        behavior:      'twitter-share',
        twittertext:   TwitterProductShare.new(product).return_text,
        twitterurl:    product_url(product),
        twitteranchor: 'twitteranchor'
      }
    
      link_to(class: 'twitter-share', data: data) do
        tag(:i, class: 'fa fa-lg fa-twitter')
      end
    end
    

    在你看来,像这样使用这个助手:

    <%= twitter_share_link(@product) %>
    

    或者您甚至可以从 TwitterProductShare 返回整个 data 哈希。

    【讨论】:

    • 感谢斯派克曼!你能告诉我一些关于TwitterProductShare类的事情吗?把所有方法都放在那个类中好吗?除此之外,可以将该类放入app/services 文件夹还是应该放在其他地方?
    • 我认为将所有方法组合在一个TwitterProductShare 类中的一个位置是非常有意义的,因为它们都用于生成 Twitter 链接。我会将该类放在app/models 文件夹中。我认为没有理由拥有 services 文件夹。
    • spickermann,将这些类(不是 AR)放到其他地方,比如 lib 文件夹或 services 文件夹中不是更好吗?
    • 这主要是基于意见的。我认为 PORO(普通旧 Ruby 对象)仍然可能是 MVC(模型-视图-控制器)中 M 含义的模型。在您的示例中,该类表示您的业务域中的模型,因此属于 models 文件夹。但是您也可以争辩说它与您的应用程序无关,因此应该位于 lib 文件夹中,或者应该提取到 gem 中。只要您的团队同意,我认为两者都可以。
    猜你喜欢
    • 2021-08-29
    • 2010-11-30
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    相关资源
    最近更新 更多