Reputation: 4395
Would this be considered bad practice?
unless Link.exists?(:href => 'example.com/somepage')
Domain.where(:domain => 'example.com').first.links.create(:href => 'example.com/somepage', :text => 'Some Page')
end
I realize I might be requesting more data then I actually need, can I optimize this somehow?
Domain is a unique index so the lookup should be fairly quick.
Running Rails 3.0.7
Upvotes: 2
Views: 178
Reputation: 83680
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
Or you can use extended update_or_create_by_*
method:
Domain.update_or_create_by_href('example.com/somepage') do |domain|
domain.text = "My Text"
end
More info here:
find_or_create_by in Rails 3 and updating for creating records
Upvotes: 2
Reputation: 2534
You can refactor your code in this manner:
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')
In both cases (your and mine) you get two request (like so):
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')
But with this code you're also protected from unknown domains, so Link
'd create one automatically.
Also you can use validates uniqueness so you can remove all unless Link.exists?(:href => '...')
.
Upvotes: 3