我想输出一个成员(member)链接列表,每个链接都标记为标识当前用户。用HTML会很简单,但是我们正在编写一个API,所以输出是JSON。

我有它的工作,但似乎过于复杂。这是最好的方法吗?

我的模型AffiliateLink包含一个字段(链接的原始HTML),我将通过添加 token 即时对其进行转换和输出。我有一个产生替换的模型方法-这是不平凡的,因为我们使用多个子公司,并且每个子公司都有一个特殊的转换规则,该方法知道:

def link_with_token(user_token)
  # some gnarly code that depends on a lot of stuff the model knows
  # that returns a proper link
end

为了在JSON中获取正确的链接html,我已经做了以下事情:
  • attr_accessor :link_html添加到模型
  • 添加一个实例方法来设置新的访问器

  • ...
    def set_link_html(token)
      self.link_html = link_with_tracking_token(token)
    end
    
  • 覆盖模型中的as_json,将原始的html_code替换为link_html

  • ...
    def as_json(options = {})
      super(:methods => :link_html, :except => :html_code)
    end
    
  • 遍历 Controller 方法中返回的集合以进行转换

  • ...
    def index
      @links = Admin::AffiliateLink.all  # TODO, pagination, etc.
    
      respond_to do |format|
        format.html # index.html.erb
        format.json do
          @links.each do |link|
            link.set_link_html(account_tracking_token)
          end
          render json: @links
        end
      end
    end
    

    这似乎是要做很多事情才能完成我的“青少年之间”转换的工作。欢迎提供有用的建议(与这个问题有关,而不是与代码的其他方面有关(现在正在不断变化))。

    最佳答案

    1)解决问题的快速方法(如here所示):

    affiliate_links_controller.rb

    def index
      @links = Admin::AffiliateLink.all  # TODO, pagination, etc.
    
      respond_to do |format|
        format.html # index.html.erb
        format.json do
          render json: @links.to_json(:account_tracking_token => account_tracking_token)
        end
      end
    end
    

    AffiliateLink.rb
    # I advocate reverse_merge so passed-in options overwrite defaults when option
    # keys match.
    def as_json(options = {})
      json = super(options.reverse_merge(:except => :html_code))
      json[:link_with_token] = link_with_token(options[:account_tracking_token])
      json
    end
    

    2)如果您确实在编写API,则是更严格的解决方案:
  • 请参阅this article描述您的问题。
  • 请参阅作者作为解决方案制作的the gem
  • 有关使用gem的信息,请参见this railscast


  • 3)最后,便捷的解决方案。如果您有方便的模型关系,这很干净:

    假装AffiliateLink belongs_to :user。并假设user_token是User的可访问属性。

    AffiliateLink.rb
    # have access to user.user_token via relation
    def link_with_token
      # some gnarly code that depends on a lot of stuff the model knows
      # that returns a proper link
    end
    
    def as_json(options = {})
      super(options.reverse_merge(:methods => :link_with_token, :except => :html_code))
    end
    

    affiliate_links_controller.rb
    def index
      @links = Admin::AffiliateLink.all  # TODO, pagination, etc.
    
      respond_to do |format|
        format.html # index.html.erb
        format.json do
          render json: @links
        end
      end
    end
    

    关于ruby-on-rails - Rails : overriding as_json for dynamic value -- is there a smarter way?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11811757/

    10-11 06:13