{"action":"created","issue":{"url":"https://api.github.com/repos/balvig/spyke/issues/27","labels_url":"https://api.github.com/repos/balvig/spyke/issues/27/labels{/name}","comments_url":"https://api.github.com/repos/balvig/spyke/issues/27/comments","events_url":"https://api.github.com/repos/balvig/spyke/issues/27/events","html_url":"https://github.com/balvig/spyke/issues/27","id":58729099,"number":27,"title":"Make save, save! and create behave like ActiveRecord","user":{"login":"jontebol","id":87823,"avatar_url":"https://avatars.githubusercontent.com/u/87823?v=3","gravatar_id":"","url":"https://api.github.com/users/jontebol","html_url":"https://github.com/jontebol","followers_url":"https://api.github.com/users/jontebol/followers","following_url":"https://api.github.com/users/jontebol/following{/other_user}","gists_url":"https://api.github.com/users/jontebol/gists{/gist_id}","starred_url":"https://api.github.com/users/jontebol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jontebol/subscriptions","organizations_url":"https://api.github.com/users/jontebol/orgs","repos_url":"https://api.github.com/users/jontebol/repos","events_url":"https://api.github.com/users/jontebol/events{/privacy}","received_events_url":"https://api.github.com/users/jontebol/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-02-24T12:02:50Z","updated_at":"2015-03-02T08:20:27Z","closed_at":null,"body":"My third suggestion for today, hope you don't think I'm a pain in the *... ;)\r\n\r\nI'm building a client based on Spyke, and in my base class (which inherits from Spyke::Base) I've added the following:\r\n````\r\n    def self.create(attrs = {})\r\n      instance = self.new(attrs)\r\n      instance.save!\r\n      return instance\r\n    end\r\n\r\n    def save\r\n      errors.clear\r\n      super\r\n      return !errors.any?\r\n    end\r\n\r\n    def save!\r\n      raise BlaBla::Error::ResourceInvalid, self.errors unless self.save\r\n    end\r\n```\r\n\r\nThis makes Spyke behave more like ActiveRecord, so that save returns true or false, while save! and create raise errors if validation failes.\r\n\r\nI'm not suggesting you use this code, just that it might be a good idea to make Spyke behave more like ActiveRecord on those methods."},"comment":{"url":"https://api.github.com/repos/balvig/spyke/issues/comments/76673151","html_url":"https://github.com/balvig/spyke/issues/27#issuecomment-76673151","issue_url":"https://api.github.com/repos/balvig/spyke/issues/27","id":76673151,"user":{"login":"jontebol","id":87823,"avatar_url":"https://avatars.githubusercontent.com/u/87823?v=3","gravatar_id":"","url":"https://api.github.com/users/jontebol","html_url":"https://github.com/jontebol","followers_url":"https://api.github.com/users/jontebol/followers","following_url":"https://api.github.com/users/jontebol/following{/other_user}","gists_url":"https://api.github.com/users/jontebol/gists{/gist_id}","starred_url":"https://api.github.com/users/jontebol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jontebol/subscriptions","organizations_url":"https://api.github.com/users/jontebol/orgs","repos_url":"https://api.github.com/users/jontebol/repos","events_url":"https://api.github.com/users/jontebol/events{/privacy}","received_events_url":"https://api.github.com/users/jontebol/received_events","type":"User","site_admin":false},"created_at":"2015-03-02T08:20:27Z","updated_at":"2015-03-02T08:20:27Z","body":"You are right about my use case. I haven't planned on using any client side validations, although I'm sure there are use cases where they would be nice to have. But does it really matter to this discussion? The way Spyke works it already behaves similarly for errors from the API and locally, right? In both cases it adds errors to the model, so what would be the difference? \"valid?\" would always be a local call in any case (right?), so that way you could check your client side validations first if you like. And the way I implemented save, it would clear any errors before trying again so you could easily do both.\r\n\r\nAbout how AR works... It's funny because I was sure it was as you say (that \"bang\"-versions raise errors), so I checked it out before posting this issue (because I wanted my client-lib to be as AR-like as possible, that's how I even discovered this in the first place) and to my surprise found that there was no \"create!\"-method and that the regular \"create\"-method raised errors. Now however, when I try to find confirmation of this, I realize I must have been either drunk or mad from sleep depravation when I looked it up last time. Of course that's how AR works!! :P Or else, I decided that's how I wanted my own client-lib to behave and (in my crazy state of mind that I was obviously in) transposed that behaviour onto AR. Oh, well, the original intent behind this issue still holds. :) So in case someone else finds this and would like to copy my code, here's the updated versionen that works similiar to AR:\r\n\r\n```Ruby\r\n    def self.create!(attrs = {})\r\n      instance = self.new(attrs)\r\n      instance.save!\r\n      return instance\r\n    end\r\n\r\n    def self.create(attrs = {})\r\n      instance = self.new(attrs)\r\n      instance.save\r\n      return instance\r\n    end\r\n\r\n    def save\r\n      errors.clear\r\n      super\r\n      return !errors.any?\r\n    end\r\n\r\n    def save!\r\n      raise BlaBla::Error::ResourceInvalid, self.errors unless self.save\r\n    end\r\n```"}}