Rails - 这是一种不好的做法还是可以优化?

时间:2011-04-26 08:05:20

标签: ruby-on-rails rails-activerecord

这会被视为不良做法吗?

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

我意识到我可能会请求更多数据然后我真的需要,我能以某种方式对其进行优化吗?

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

运行Rails 3.0.7

2 个答案:

答案 0 :(得分:3)

您可以通过以下方式重构代码:

域类

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 => '...')

答案 1 :(得分: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