{"action":"closed","issue":{"url":"https://api.github.com/repos/contentful/contentful_model/issues/65","repository_url":"https://api.github.com/repos/contentful/contentful_model","labels_url":"https://api.github.com/repos/contentful/contentful_model/issues/65/labels{/name}","comments_url":"https://api.github.com/repos/contentful/contentful_model/issues/65/comments","events_url":"https://api.github.com/repos/contentful/contentful_model/issues/65/events","html_url":"https://github.com/contentful/contentful_model/issues/65","id":219353503,"number":65,"title":"ContentfulModel::Base doesn't provide a #hash method","user":{"login":"georgebrock","id":35861,"avatar_url":"https://avatars2.githubusercontent.com/u/35861?v=3","gravatar_id":"","url":"https://api.github.com/users/georgebrock","html_url":"https://github.com/georgebrock","followers_url":"https://api.github.com/users/georgebrock/followers","following_url":"https://api.github.com/users/georgebrock/following{/other_user}","gists_url":"https://api.github.com/users/georgebrock/gists{/gist_id}","starred_url":"https://api.github.com/users/georgebrock/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/georgebrock/subscriptions","organizations_url":"https://api.github.com/users/georgebrock/orgs","repos_url":"https://api.github.com/users/georgebrock/repos","events_url":"https://api.github.com/users/georgebrock/events{/privacy}","received_events_url":"https://api.github.com/users/georgebrock/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2017-04-04T19:13:44Z","updated_at":"2017-07-07T19:03:01Z","closed_at":"2017-07-07T19:03:01Z","body":"`ContentfulModel::Base` doesn't provide a `#hash` method, so model instances cannot be effectively used as keys in Hashes, or easily filtered for duplicates.\r\n\r\nFor example, I have a `Requirement` model which `has_one` `Category`. After loading my requirements, I group them by category:\r\n\r\n```ruby\r\nrequirements.group_by(&:category)\r\n  # => {<Category> => [<Requirement>, <Requirement>, …], …}\r\n```\r\n\r\nFor the results of a single query, this works fine. However, sometimes I want to combine the results of two queries, to simulate a logical `OR`:\r\n\r\n```ruby\r\n(some_requirements + other_requirements).uniq.group_by(&:category)\r\n```\r\n\r\nThis throws up two problems, both arising from the lack of `#hash`:\r\n\r\n1. Duplicate requirements from the two queries are different objects, and since they inherit the default implementation of `#hash`, they're not filtered out by `#uniq`.\r\n2. Any category that was present in both sets of results ends up as two different keys in the resulting Hash, again because they are different objects.\r\n\r\n## Possible solutions\r\n\r\nIn my app, I added `#hash` and `#eql?` methods based closely on [ActiveRecord's implementation][1]:\r\n\r\n```ruby\r\n  def eql?(other)\r\n    super || other.instance_of?(self.class) && id.present? && other.id == id\r\n  end\r\n\r\n  def hash\r\n    if id.present?\r\n      self.class.hash ^ id.hash\r\n    else\r\n      super\r\n    end\r\n  end\r\n```\r\n\r\n[1]: https://github.com/rails/rails/blob/e79a991ccfdf3b7b56562be35b996e61d7395861/activerecord/lib/active_record/core.rb#L441-L457"}}
{"actor":{"display_login":"dlitvakb"}}