I have a list of hashes, as such:
incoming_links = [
{:title => 'blah1', :url => "http://blah.com/post/1"},
{:title => 'blah2', :url => "http://blah.com/post/2"},
{:title => 'blah3', :url => "http://blah.com/post/3"}]
And an ActiveRecord model which has fields in the database with some matching rows, say:
Link.all =>
[<Link#2 @title='blah2' @url='...post/2'>,
<Link#3 @title='blah3' @url='...post/3'>,
<Link#4 @title='blah4' @url='...post/4'>]
I'd like to do set operations on Link.all
with incoming_links
so that I can figure out that <Link#4 ...>
is not in the set of incoming_links
, and {:title => 'blah1', :url =>'http://blah.com/post/1'}
is not in the Link.all
set, like so:
#pseudocode
#incoming_links = as above
links = Link.all
expired_links = links - incoming_links
missing_links = incoming_links - links
expired_links.destroy
missing_links.each{|link| Link.create(link)}
Crappy solution a):
I'd rather not rewrite Array#-
and such, and I'm okay with converting incoming_links
to a set of unsaved Link
objects; so I've tried overwriting hash
eql?
and so on in Link
so that it ignored the id
equality that AR::Base
provides by default. But this is the only place this sort of equality should be considered in the application - in other places the Link#id default identity is required. Is there some way I could subclass Link and apply the hash
, eql?
, etc overwriting there?
Crappy solution b):
The other route I've tried is to pull out the attributes hash for each Link and doing a .slice('id',...etc)
to prune the hashes down. But this requires writing seperate -
methods for keeping track of the Link objects while doing set operations on the hashes, and writing seperate Proxy classes to wrap the incoming_links
hashes and Links, which seems a bit overkill. Nonetheless, this is the current solution for me.
Can you think of a better way to design this interaction? Extra credit for cleanliness.