{"action":"created","comment":{"url":"https://api.github.com/repos/zilverline/sequent/pulls/comments/28220086","id":28220086,"diff_hunk":"@@ -0,0 +1,76 @@\n+require_relative '../ext/ext'\n+require_relative 'array_with_type'\n+\n+module Sequent\n+  module Core\n+    module Helpers\n+      class StringToValueParsers\n+        PARSERS = {\n+          ::Symbol => ->(value) { Symbol.deserialize_from_json(value) },\n+          ::String => ->(value) { value },\n+          ::Integer => ->(value) { parse_to_integer(value) },\n+          ::Boolean => ->(value) { parse_to_bool(value) },\n+          ::Date => ->(value) { parse_to_date(value) },\n+          ::DateTime => ->(value) { parse_to_date_time(value) },\n+          ::Sequent::Core::Helpers::ArrayWithType => ->(values, type_in_array) { parse_array(values, type_in_array) }\n+        }\n+\n+        def self.parse_to_integer(value)\n+          Integer(value) unless value.blank?","path":"lib/sequent/core/helpers/string_to_value_parsers.rb","position":19,"original_position":19,"commit_id":"8bf3d730d1b573c217c360833a6718c94186543e","original_commit_id":"8bf3d730d1b573c217c360833a6718c94186543e","user":{"login":"derekkraan","id":522157,"avatar_url":"https://avatars.githubusercontent.com/u/522157?v=3","gravatar_id":"","url":"https://api.github.com/users/derekkraan","html_url":"https://github.com/derekkraan","followers_url":"https://api.github.com/users/derekkraan/followers","following_url":"https://api.github.com/users/derekkraan/following{/other_user}","gists_url":"https://api.github.com/users/derekkraan/gists{/gist_id}","starred_url":"https://api.github.com/users/derekkraan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/derekkraan/subscriptions","organizations_url":"https://api.github.com/users/derekkraan/orgs","repos_url":"https://api.github.com/users/derekkraan/repos","events_url":"https://api.github.com/users/derekkraan/events{/privacy}","received_events_url":"https://api.github.com/users/derekkraan/received_events","type":"User","site_admin":false},"body":"We never do anything with `Integer(value)`. Is it necessary?","created_at":"2015-04-13T07:57:52Z","updated_at":"2015-04-13T07:57:52Z","html_url":"https://github.com/zilverline/sequent/pull/2#discussion_r28220086","pull_request_url":"https://api.github.com/repos/zilverline/sequent/pulls/2","_links":{"self":{"href":"https://api.github.com/repos/zilverline/sequent/pulls/comments/28220086"},"html":{"href":"https://github.com/zilverline/sequent/pull/2#discussion_r28220086"},"pull_request":{"href":"https://api.github.com/repos/zilverline/sequent/pulls/2"}}},"pull_request":{"url":"https://api.github.com/repos/zilverline/sequent/pulls/2","id":32712543,"html_url":"https://github.com/zilverline/sequent/pull/2","diff_url":"https://github.com/zilverline/sequent/pull/2.diff","patch_url":"https://github.com/zilverline/sequent/pull/2.patch","issue_url":"https://api.github.com/repos/zilverline/sequent/issues/2","number":2,"state":"open","locked":false,"title":"Validation and conversion support","user":{"login":"lvonk","id":104943,"avatar_url":"https://avatars.githubusercontent.com/u/104943?v=3","gravatar_id":"","url":"https://api.github.com/users/lvonk","html_url":"https://github.com/lvonk","followers_url":"https://api.github.com/users/lvonk/followers","following_url":"https://api.github.com/users/lvonk/following{/other_user}","gists_url":"https://api.github.com/users/lvonk/gists{/gist_id}","starred_url":"https://api.github.com/users/lvonk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lvonk/subscriptions","organizations_url":"https://api.github.com/users/lvonk/orgs","repos_url":"https://api.github.com/users/lvonk/repos","events_url":"https://api.github.com/users/lvonk/events{/privacy}","received_events_url":"https://api.github.com/users/lvonk/received_events","type":"User","site_admin":false},"body":"Validation and conversion was a bit messy. This is the first attempt to clean up and avoid usual repetition when creating Commands and ValueObjects.\r\n\r\nPrior to this PR you have to:\r\n```\r\nclass MyCommand < Sequent::Core::BaseCommand\r\n    attrs number: Integer, \r\n          date: Date, \r\n          date_time: DateTime, \r\n          list_of_numbers: array(Integer), \r\n          user: Person\r\n    \r\n    validates_numericality_of :number, only_integer: true\r\n    #custom validator for date needed\r\n    #custom validator for datetime needed\r\n    validates_with Sequent::Core::AssociationValidator, associations: [:list_of_numbers, :user]\r\n\r\nend\r\n```\r\n\r\nAnd parse Integers and DateTime yourself. This made form binding a bit cumbersome and hard to work with.\r\n\r\nWith this PR all expected validations - like Integers being an Integer (or valid string as Integers), Dates being a Date (or valid string as Dates) etc etc - are added by default. Presence is still optional and you should still add it yourself if needed.\r\n\r\nSo the above can be rewritten as follows:\r\n```\r\nclass MyCommand < Sequent::Core::BaseCommand\r\n    attrs number: Integer, \r\n          date: Date, \r\n          date_time: DateTime, \r\n          list_of_numbers: array(Integer), \r\n          user: Person\r\nend\r\n```\r\n\r\nFurthermore the `CommandService` will parse all values to their correct types (the supported ones are in the README) after the `Command` is `valid?`.","created_at":"2015-04-06T21:18:41Z","updated_at":"2015-04-13T07:57:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"78d30a5bf2e694e8c24be7c7b1ab25e88eeaf302","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/zilverline/sequent/pulls/2/commits","review_comments_url":"https://api.github.com/repos/zilverline/sequent/pulls/2/comments","review_comment_url":"https://api.github.com/repos/zilverline/sequent/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zilverline/sequent/issues/2/comments","statuses_url":"https://api.github.com/repos/zilverline/sequent/statuses/8bf3d730d1b573c217c360833a6718c94186543e","head":{"label":"zilverline:validation-conversion","ref":"validation-conversion","sha":"8bf3d730d1b573c217c360833a6718c94186543e","user":{"login":"zilverline","id":159022,"avatar_url":"https://avatars.githubusercontent.com/u/159022?v=3","gravatar_id":"","url":"https://api.github.com/users/zilverline","html_url":"https://github.com/zilverline","followers_url":"https://api.github.com/users/zilverline/followers","following_url":"https://api.github.com/users/zilverline/following{/other_user}","gists_url":"https://api.github.com/users/zilverline/gists{/gist_id}","starred_url":"https://api.github.com/users/zilverline/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zilverline/subscriptions","organizations_url":"https://api.github.com/users/zilverline/orgs","repos_url":"https://api.github.com/users/zilverline/repos","events_url":"https://api.github.com/users/zilverline/events{/privacy}","received_events_url":"https://api.github.com/users/zilverline/received_events","type":"Organization","site_admin":false},"repo":{"id":32690099,"name":"sequent","full_name":"zilverline/sequent","owner":{"login":"zilverline","id":159022,"avatar_url":"https://avatars.githubusercontent.com/u/159022?v=3","gravatar_id":"","url":"https://api.github.com/users/zilverline","html_url":"https://github.com/zilverline","followers_url":"https://api.github.com/users/zilverline/followers","following_url":"https://api.github.com/users/zilverline/following{/other_user}","gists_url":"https://api.github.com/users/zilverline/gists{/gist_id}","starred_url":"https://api.github.com/users/zilverline/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zilverline/subscriptions","organizations_url":"https://api.github.com/users/zilverline/orgs","repos_url":"https://api.github.com/users/zilverline/repos","events_url":"https://api.github.com/users/zilverline/events{/privacy}","received_events_url":"https://api.github.com/users/zilverline/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zilverline/sequent","description":"CQRS & event sourcing framework for Ruby","fork":false,"url":"https://api.github.com/repos/zilverline/sequent","forks_url":"https://api.github.com/repos/zilverline/sequent/forks","keys_url":"https://api.github.com/repos/zilverline/sequent/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zilverline/sequent/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zilverline/sequent/teams","hooks_url":"https://api.github.com/repos/zilverline/sequent/hooks","issue_events_url":"https://api.github.com/repos/zilverline/sequent/issues/events{/number}","events_url":"https://api.github.com/repos/zilverline/sequent/events","assignees_url":"https://api.github.com/repos/zilverline/sequent/assignees{/user}","branches_url":"https://api.github.com/repos/zilverline/sequent/branches{/branch}","tags_url":"https://api.github.com/repos/zilverline/sequent/tags","blobs_url":"https://api.github.com/repos/zilverline/sequent/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zilverline/sequent/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zilverline/sequent/git/refs{/sha}","trees_url":"https://api.github.com/repos/zilverline/sequent/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zilverline/sequent/statuses/{sha}","languages_url":"https://api.github.com/repos/zilverline/sequent/languages","stargazers_url":"https://api.github.com/repos/zilverline/sequent/stargazers","contributors_url":"https://api.github.com/repos/zilverline/sequent/contributors","subscribers_url":"https://api.github.com/repos/zilverline/sequent/subscribers","subscription_url":"https://api.github.com/repos/zilverline/sequent/subscription","commits_url":"https://api.github.com/repos/zilverline/sequent/commits{/sha}","git_commits_url":"https://api.github.com/repos/zilverline/sequent/git/commits{/sha}","comments_url":"https://api.github.com/repos/zilverline/sequent/comments{/number}","issue_comment_url":"https://api.github.com/repos/zilverline/sequent/issues/comments{/number}","contents_url":"https://api.github.com/repos/zilverline/sequent/contents/{+path}","compare_url":"https://api.github.com/repos/zilverline/sequent/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zilverline/sequent/merges","archive_url":"https://api.github.com/repos/zilverline/sequent/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zilverline/sequent/downloads","issues_url":"https://api.github.com/repos/zilverline/sequent/issues{/number}","pulls_url":"https://api.github.com/repos/zilverline/sequent/pulls{/number}","milestones_url":"https://api.github.com/repos/zilverline/sequent/milestones{/number}","notifications_url":"https://api.github.com/repos/zilverline/sequent/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zilverline/sequent/labels{/name}","releases_url":"https://api.github.com/repos/zilverline/sequent/releases{/id}","created_at":"2015-03-22T18:56:51Z","updated_at":"2015-04-06T08:36:45Z","pushed_at":"2015-04-12T17:39:33Z","git_url":"git://github.com/zilverline/sequent.git","ssh_url":"git@github.com:zilverline/sequent.git","clone_url":"https://github.com/zilverline/sequent.git","svn_url":"https://github.com/zilverline/sequent","homepage":"","size":565,"stargazers_count":3,"watchers_count":3,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":3,"forks":1,"open_issues":3,"watchers":3,"default_branch":"master"}},"base":{"label":"zilverline:master","ref":"master","sha":"2bde3505e4fe9ad89a88938b8c0f77e20b1d94a9","user":{"login":"zilverline","id":159022,"avatar_url":"https://avatars.githubusercontent.com/u/159022?v=3","gravatar_id":"","url":"https://api.github.com/users/zilverline","html_url":"https://github.com/zilverline","followers_url":"https://api.github.com/users/zilverline/followers","following_url":"https://api.github.com/users/zilverline/following{/other_user}","gists_url":"https://api.github.com/users/zilverline/gists{/gist_id}","starred_url":"https://api.github.com/users/zilverline/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zilverline/subscriptions","organizations_url":"https://api.github.com/users/zilverline/orgs","repos_url":"https://api.github.com/users/zilverline/repos","events_url":"https://api.github.com/users/zilverline/events{/privacy}","received_events_url":"https://api.github.com/users/zilverline/received_events","type":"Organization","site_admin":false},"repo":{"id":32690099,"name":"sequent","full_name":"zilverline/sequent","owner":{"login":"zilverline","id":159022,"avatar_url":"https://avatars.githubusercontent.com/u/159022?v=3","gravatar_id":"","url":"https://api.github.com/users/zilverline","html_url":"https://github.com/zilverline","followers_url":"https://api.github.com/users/zilverline/followers","following_url":"https://api.github.com/users/zilverline/following{/other_user}","gists_url":"https://api.github.com/users/zilverline/gists{/gist_id}","starred_url":"https://api.github.com/users/zilverline/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zilverline/subscriptions","organizations_url":"https://api.github.com/users/zilverline/orgs","repos_url":"https://api.github.com/users/zilverline/repos","events_url":"https://api.github.com/users/zilverline/events{/privacy}","received_events_url":"https://api.github.com/users/zilverline/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zilverline/sequent","description":"CQRS & event sourcing framework for Ruby","fork":false,"url":"https://api.github.com/repos/zilverline/sequent","forks_url":"https://api.github.com/repos/zilverline/sequent/forks","keys_url":"https://api.github.com/repos/zilverline/sequent/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zilverline/sequent/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zilverline/sequent/teams","hooks_url":"https://api.github.com/repos/zilverline/sequent/hooks","issue_events_url":"https://api.github.com/repos/zilverline/sequent/issues/events{/number}","events_url":"https://api.github.com/repos/zilverline/sequent/events","assignees_url":"https://api.github.com/repos/zilverline/sequent/assignees{/user}","branches_url":"https://api.github.com/repos/zilverline/sequent/branches{/branch}","tags_url":"https://api.github.com/repos/zilverline/sequent/tags","blobs_url":"https://api.github.com/repos/zilverline/sequent/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zilverline/sequent/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zilverline/sequent/git/refs{/sha}","trees_url":"https://api.github.com/repos/zilverline/sequent/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zilverline/sequent/statuses/{sha}","languages_url":"https://api.github.com/repos/zilverline/sequent/languages","stargazers_url":"https://api.github.com/repos/zilverline/sequent/stargazers","contributors_url":"https://api.github.com/repos/zilverline/sequent/contributors","subscribers_url":"https://api.github.com/repos/zilverline/sequent/subscribers","subscription_url":"https://api.github.com/repos/zilverline/sequent/subscription","commits_url":"https://api.github.com/repos/zilverline/sequent/commits{/sha}","git_commits_url":"https://api.github.com/repos/zilverline/sequent/git/commits{/sha}","comments_url":"https://api.github.com/repos/zilverline/sequent/comments{/number}","issue_comment_url":"https://api.github.com/repos/zilverline/sequent/issues/comments{/number}","contents_url":"https://api.github.com/repos/zilverline/sequent/contents/{+path}","compare_url":"https://api.github.com/repos/zilverline/sequent/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zilverline/sequent/merges","archive_url":"https://api.github.com/repos/zilverline/sequent/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zilverline/sequent/downloads","issues_url":"https://api.github.com/repos/zilverline/sequent/issues{/number}","pulls_url":"https://api.github.com/repos/zilverline/sequent/pulls{/number}","milestones_url":"https://api.github.com/repos/zilverline/sequent/milestones{/number}","notifications_url":"https://api.github.com/repos/zilverline/sequent/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zilverline/sequent/labels{/name}","releases_url":"https://api.github.com/repos/zilverline/sequent/releases{/id}","created_at":"2015-03-22T18:56:51Z","updated_at":"2015-04-06T08:36:45Z","pushed_at":"2015-04-12T17:39:33Z","git_url":"git://github.com/zilverline/sequent.git","ssh_url":"git@github.com:zilverline/sequent.git","clone_url":"https://github.com/zilverline/sequent.git","svn_url":"https://github.com/zilverline/sequent","homepage":"","size":565,"stargazers_count":3,"watchers_count":3,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":3,"forks":1,"open_issues":3,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zilverline/sequent/pulls/2"},"html":{"href":"https://github.com/zilverline/sequent/pull/2"},"issue":{"href":"https://api.github.com/repos/zilverline/sequent/issues/2"},"comments":{"href":"https://api.github.com/repos/zilverline/sequent/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/zilverline/sequent/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/zilverline/sequent/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zilverline/sequent/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/zilverline/sequent/statuses/8bf3d730d1b573c217c360833a6718c94186543e"}}}}