【问题标题】:Rails - is this bad practice or can this be optimized?Rails - 这是不好的做法还是可以优化?
【发布时间】:2011-04-26 08:05:19
【问题描述】:

这会被认为是不好的做法吗?

unless Link.exists?(:href => 'example.com/somepage')
  Domain.where(:domain => 'example.com').first.links.create(:href => 'example.com/somepage', :text => 'Some Page')
end

我意识到我请求的数据可能比我实际需要的多,我可以以某种方式对其进行优化吗?

域是一个唯一索引,因此查找应该相当快。

运行 Rails 3.0.7

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案1】:

    你可以用这种方式重构你的代码:

    域类

    class Domain < ActiveRecord::Base
      has_many :links
    end
    

    链接类

    class Link < ActiveRecord::Base
      belongs_to :domain
    
      validates :href,
                :uniqueness => true
    
      attr :domain_url
    
      def domain_url=(main_domain_url)
        self.domain = Domain.where(domain: main_domain_url).first ||
                      Domain.new(domain: main_domain_url)
      end
    
      def domain_url
        self.domain.nil? ? '' : self.domain.domain_url
      end
    end
    

    用法

    Link.create(href: 'example.com/somepage',
                text: 'Some Page',
                domain_url: 'example.com')
    

    结论

    在这两种情况下(你的和我的)你都会收到两个请求(就像这样):

    Domain Load (1.0ms)  SELECT "domains".* FROM "domains" WHERE "domains"."domain" = 'example.com' LIMIT 1
      AREL (0.1ms)  INSERT INTO "links" ("href", "text", "domain_id", "created_at", "updated_at") VALUES ('example.com/somepage', 'Some Page', 5, '2011-04-26 08:51:20.373523', '2011-04-26 08:51:20.373523')
    

    但使用此代码,您还可以免受未知域的侵害,因此 Link 会自动创建一个。

    您还可以使用验证唯一性,以便删除所有 unless Link.exists?(:href =&gt; '...')

    【讨论】:

    • 从中学到了一些新东西,感谢您的贡献。
    【解决方案2】:
    Domain.where(:domain => 'example.com').
      first.links.
      find_or_create_by_href_and_text(:href => 'example.com/somepage', :text => "Some Page")
    

    UPD

    @domain = Domain.where(:domain => 'example.com').
                first.links.
                find_or_create_by_href('example.com/somepage')
    @domain.text = "My Text"
    @domain.save
    

    或者你可以使用扩展的update_or_create_by_* 方法:

    Domain.update_or_create_by_href('example.com/somepage') do |domain|
      domain.text = "My Text"
    end
    

    更多信息在这里:

    find_or_create_by in Rails 3 and updating for creating records

    【讨论】:

    • find_or_create 不会同时匹配 href 和 text 吗?如果我删除 _and_text 它只会匹配 href,对吗?
    • 抱歉,我不确定我是否关注.. 我需要能够添加 :text,但我只想匹配 :href
    猜你喜欢
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    相关资源
    最近更新 更多