{"action":"created","comment":{"url":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/comments/50730927","id":50730927,"diff_hunk":"@@ -112,6 +114,57 @@ def extract_model(model_spec)\n       return result\n     end\n \n+    # IMPORTANT: For this method to work, we are making the assumption that expand_spec_properties as already been\n+    #            enacted on model_spec, per call from build_hashie\n+    def extract_sql_from_hashie(hashie, model_spec)\n+      # Build the SQL for the current level\n+      sql_output = ''\n+      base_model = model_spec[:base_model]\n+      columns = model_spec[:columns]\n+      associations = model_spec[:associations]\n+\n+      hashie.each do |model_data|\n+        sql_output << build_sql_insert_statement(base_model.table_name, attributes_from_model_data(model_data))\n+\n+        next unless associations.present?\n+        associations.each do |association|\n+          sub_hashie = model_data.send(association[:association_name])\n+          sql_output << extract_sql_from_hashie(sub_hashie, association)\n+        end\n+      end\n+      sql_output\n+    end\n+\n+    def attributes_from_model_data(hashie)\n+      hashie.reject { |_k,v| v.is_a? Array }  # associations would be of type Array\n+    end\n+\n+    # Builds the output INSERT SQL statements to build the data fixtures\n+    def build_sql_insert_statement(table_name, attributes={})\n+      return if attributes.empty?\n+      \"INSERT INTO #{table_name} (#{attributes.keys.join(',')}) VALUES (#{sql_safe(attributes.values).join(',')});\\n\"\n+    end\n+\n+    # Takes an array of values, converts each one to a SQL-friendly text string\n+    def sql_safe(values)\n+      values.map do |val|\n+        case val.class.to_s # I convert to string because for some reason if val.class is Fixnum, val.class === Fixnum == false","path":"lib/production_sampler.rb","position":null,"original_position":81,"commit_id":"b49a1bff1d14af90b3fcf6957b8f91d91ef0e49c","original_commit_id":"6168d77a25cdc372f1b76e116ca01f505d4284a1","user":{"login":"Ferdy89","id":1112217,"avatar_url":"https://avatars.githubusercontent.com/u/1112217?v=3","gravatar_id":"","url":"https://api.github.com/users/Ferdy89","html_url":"https://github.com/Ferdy89","followers_url":"https://api.github.com/users/Ferdy89/followers","following_url":"https://api.github.com/users/Ferdy89/following{/other_user}","gists_url":"https://api.github.com/users/Ferdy89/gists{/gist_id}","starred_url":"https://api.github.com/users/Ferdy89/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ferdy89/subscriptions","organizations_url":"https://api.github.com/users/Ferdy89/orgs","repos_url":"https://api.github.com/users/Ferdy89/repos","events_url":"https://api.github.com/users/Ferdy89/events{/privacy}","received_events_url":"https://api.github.com/users/Ferdy89/received_events","type":"User","site_admin":false},"body":"Read the link I posted, the thing is that the `===` is not really about comparison","created_at":"2016-01-25T18:06:04Z","updated_at":"2016-01-25T18:06:04Z","html_url":"https://github.com/wkotzan-avant/production_sampler/pull/1#discussion_r50730927","pull_request_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/comments/50730927"},"html":{"href":"https://github.com/wkotzan-avant/production_sampler/pull/1#discussion_r50730927"},"pull_request":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/1","id":57030008,"html_url":"https://github.com/wkotzan-avant/production_sampler/pull/1","diff_url":"https://github.com/wkotzan-avant/production_sampler/pull/1.diff","patch_url":"https://github.com/wkotzan-avant/production_sampler/pull/1.patch","issue_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues/1","number":1,"state":"open","locked":false,"title":"Add sql insert statement output","user":{"login":"wkotzan-avant","id":13108774,"avatar_url":"https://avatars.githubusercontent.com/u/13108774?v=3","gravatar_id":"","url":"https://api.github.com/users/wkotzan-avant","html_url":"https://github.com/wkotzan-avant","followers_url":"https://api.github.com/users/wkotzan-avant/followers","following_url":"https://api.github.com/users/wkotzan-avant/following{/other_user}","gists_url":"https://api.github.com/users/wkotzan-avant/gists{/gist_id}","starred_url":"https://api.github.com/users/wkotzan-avant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wkotzan-avant/subscriptions","organizations_url":"https://api.github.com/users/wkotzan-avant/orgs","repos_url":"https://api.github.com/users/wkotzan-avant/repos","events_url":"https://api.github.com/users/wkotzan-avant/events{/privacy}","received_events_url":"https://api.github.com/users/wkotzan-avant/received_events","type":"User","site_admin":false},"body":"@MissingHandle @bintlopez @robb-broome @cngraf @dvanderbeek @ferdy89\r\n\r\nEnhancements to the Production Sampler gem. It could be used to pull data from a production environment as SQL INSERT statements that could be used to load the data into another DB, such as a development or test environment. I'm using it to better replicate the bug that I am currently working to fix, since it could not be replicated in a simple test.\r\n\r\nIf you're unfamiliar, Production Sampler is currently used in the credit line interactor system as a means of pulling all required data about the credit line into an in-memory data source. This is a much more efficient approach than relying on the ActiveRecord models, which would query the database many times for a single business logic transaction.\r\n\r\nI'd like to do some major refactoring of Production Sampler. All of the code resides in a single file. The concerns should actually be separated into modules. But I'll worry about that later as I am trying to fry bigger fish for now.","created_at":"2016-01-25T05:23:41Z","updated_at":"2016-01-25T18:06:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"048ef923aed238e9e0777cbaef5a1716abf8d76d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/1/commits","review_comments_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/1/comments","review_comment_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/comments{/number}","comments_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues/1/comments","statuses_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/statuses/b49a1bff1d14af90b3fcf6957b8f91d91ef0e49c","head":{"label":"wkotzan-avant:add_sql_insert_statement_output","ref":"add_sql_insert_statement_output","sha":"b49a1bff1d14af90b3fcf6957b8f91d91ef0e49c","user":{"login":"wkotzan-avant","id":13108774,"avatar_url":"https://avatars.githubusercontent.com/u/13108774?v=3","gravatar_id":"","url":"https://api.github.com/users/wkotzan-avant","html_url":"https://github.com/wkotzan-avant","followers_url":"https://api.github.com/users/wkotzan-avant/followers","following_url":"https://api.github.com/users/wkotzan-avant/following{/other_user}","gists_url":"https://api.github.com/users/wkotzan-avant/gists{/gist_id}","starred_url":"https://api.github.com/users/wkotzan-avant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wkotzan-avant/subscriptions","organizations_url":"https://api.github.com/users/wkotzan-avant/orgs","repos_url":"https://api.github.com/users/wkotzan-avant/repos","events_url":"https://api.github.com/users/wkotzan-avant/events{/privacy}","received_events_url":"https://api.github.com/users/wkotzan-avant/received_events","type":"User","site_admin":false},"repo":{"id":43017154,"name":"production_sampler","full_name":"wkotzan-avant/production_sampler","owner":{"login":"wkotzan-avant","id":13108774,"avatar_url":"https://avatars.githubusercontent.com/u/13108774?v=3","gravatar_id":"","url":"https://api.github.com/users/wkotzan-avant","html_url":"https://github.com/wkotzan-avant","followers_url":"https://api.github.com/users/wkotzan-avant/followers","following_url":"https://api.github.com/users/wkotzan-avant/following{/other_user}","gists_url":"https://api.github.com/users/wkotzan-avant/gists{/gist_id}","starred_url":"https://api.github.com/users/wkotzan-avant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wkotzan-avant/subscriptions","organizations_url":"https://api.github.com/users/wkotzan-avant/orgs","repos_url":"https://api.github.com/users/wkotzan-avant/repos","events_url":"https://api.github.com/users/wkotzan-avant/events{/privacy}","received_events_url":"https://api.github.com/users/wkotzan-avant/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wkotzan-avant/production_sampler","description":"Extract fixtures from a production database","fork":false,"url":"https://api.github.com/repos/wkotzan-avant/production_sampler","forks_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/forks","keys_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/teams","hooks_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/hooks","issue_events_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues/events{/number}","events_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/events","assignees_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/assignees{/user}","branches_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/branches{/branch}","tags_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/tags","blobs_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/refs{/sha}","trees_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/statuses/{sha}","languages_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/languages","stargazers_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/stargazers","contributors_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/contributors","subscribers_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/subscribers","subscription_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/subscription","commits_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/commits{/sha}","git_commits_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/commits{/sha}","comments_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/comments{/number}","issue_comment_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues/comments{/number}","contents_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/contents/{+path}","compare_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/merges","archive_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/downloads","issues_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues{/number}","pulls_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls{/number}","milestones_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/milestones{/number}","notifications_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/labels{/name}","releases_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/releases{/id}","deployments_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/deployments","created_at":"2015-09-23T17:48:23Z","updated_at":"2015-09-23T17:49:14Z","pushed_at":"2016-01-25T17:54:30Z","git_url":"git://github.com/wkotzan-avant/production_sampler.git","ssh_url":"git@github.com:wkotzan-avant/production_sampler.git","clone_url":"https://github.com/wkotzan-avant/production_sampler.git","svn_url":"https://github.com/wkotzan-avant/production_sampler","homepage":null,"size":47,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"wkotzan-avant:master","ref":"master","sha":"81214cc098d049a7fae62e22052ac2a338a586a4","user":{"login":"wkotzan-avant","id":13108774,"avatar_url":"https://avatars.githubusercontent.com/u/13108774?v=3","gravatar_id":"","url":"https://api.github.com/users/wkotzan-avant","html_url":"https://github.com/wkotzan-avant","followers_url":"https://api.github.com/users/wkotzan-avant/followers","following_url":"https://api.github.com/users/wkotzan-avant/following{/other_user}","gists_url":"https://api.github.com/users/wkotzan-avant/gists{/gist_id}","starred_url":"https://api.github.com/users/wkotzan-avant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wkotzan-avant/subscriptions","organizations_url":"https://api.github.com/users/wkotzan-avant/orgs","repos_url":"https://api.github.com/users/wkotzan-avant/repos","events_url":"https://api.github.com/users/wkotzan-avant/events{/privacy}","received_events_url":"https://api.github.com/users/wkotzan-avant/received_events","type":"User","site_admin":false},"repo":{"id":43017154,"name":"production_sampler","full_name":"wkotzan-avant/production_sampler","owner":{"login":"wkotzan-avant","id":13108774,"avatar_url":"https://avatars.githubusercontent.com/u/13108774?v=3","gravatar_id":"","url":"https://api.github.com/users/wkotzan-avant","html_url":"https://github.com/wkotzan-avant","followers_url":"https://api.github.com/users/wkotzan-avant/followers","following_url":"https://api.github.com/users/wkotzan-avant/following{/other_user}","gists_url":"https://api.github.com/users/wkotzan-avant/gists{/gist_id}","starred_url":"https://api.github.com/users/wkotzan-avant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wkotzan-avant/subscriptions","organizations_url":"https://api.github.com/users/wkotzan-avant/orgs","repos_url":"https://api.github.com/users/wkotzan-avant/repos","events_url":"https://api.github.com/users/wkotzan-avant/events{/privacy}","received_events_url":"https://api.github.com/users/wkotzan-avant/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wkotzan-avant/production_sampler","description":"Extract fixtures from a production database","fork":false,"url":"https://api.github.com/repos/wkotzan-avant/production_sampler","forks_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/forks","keys_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/teams","hooks_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/hooks","issue_events_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues/events{/number}","events_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/events","assignees_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/assignees{/user}","branches_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/branches{/branch}","tags_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/tags","blobs_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/refs{/sha}","trees_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/statuses/{sha}","languages_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/languages","stargazers_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/stargazers","contributors_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/contributors","subscribers_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/subscribers","subscription_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/subscription","commits_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/commits{/sha}","git_commits_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/git/commits{/sha}","comments_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/comments{/number}","issue_comment_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues/comments{/number}","contents_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/contents/{+path}","compare_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/merges","archive_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/downloads","issues_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues{/number}","pulls_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls{/number}","milestones_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/milestones{/number}","notifications_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/labels{/name}","releases_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/releases{/id}","deployments_url":"https://api.github.com/repos/wkotzan-avant/production_sampler/deployments","created_at":"2015-09-23T17:48:23Z","updated_at":"2015-09-23T17:49:14Z","pushed_at":"2016-01-25T17:54:30Z","git_url":"git://github.com/wkotzan-avant/production_sampler.git","ssh_url":"git@github.com:wkotzan-avant/production_sampler.git","clone_url":"https://github.com/wkotzan-avant/production_sampler.git","svn_url":"https://github.com/wkotzan-avant/production_sampler","homepage":null,"size":47,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/1"},"html":{"href":"https://github.com/wkotzan-avant/production_sampler/pull/1"},"issue":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues/1"},"comments":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/wkotzan-avant/production_sampler/statuses/b49a1bff1d14af90b3fcf6957b8f91d91ef0e49c"}}}}