{"action":"created","comment":{"url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/comments/35892712","id":35892712,"diff_hunk":"@@ -0,0 +1,230 @@\n+#Запросы Active Record\r\n+\r\n+##Введение\r\n+\r\n+К настоящему моменту мы уже изучили основы, которые необходимы, чтобы создавать базовые запросы с помощью Active Record. А после создания еще нескольких проектов и проработки этого урока вы будете чувствовать себя уверенно, делая такие запросы. \r\n+\r\n+Active Record гораздо более мощное средство для работы с отдельными записями, чем просто действия CRUD (CRUD actions). Он предоставляет вам сочетание Ruby-подобного интерфейса и возможности делать почти все, что можно сделать с помощью \"голого\" SQL. Вы можете избирательно подходить к выбору отдельных групп записей в соответствии с конкретными критериями и упорядочивать их так, как будет угодно. Вы можете объединять (join) таблицы вручную или делать запрос с использованием ассоциаций (associations), предоставляемых Rails. Вы можете возвращать списки записей или производить над ними базовые математические операции такие, как использование счетчиков или вычисление средних.\r\n+\r\n+Все это делается на уровне базы данных, что намного быстрее, чем загрузка содержимого всей таблицы в объект Ruby перед тем, как начинать анализ, разбиение на части или какие-то подсчеты.\r\n+\r\n+В этом уроке мы познакомимся с еще более интересными и полезными возможностями запросов Active Record. Вы узнаете, что на самом деле возвращает Active Record и как манипулировать (обращаться с?) полученными значениями по вашему желанию. Попутно вы узнаете и то, как сделать запросы более эффективными\r\n+\r\n+Предстоит много прочитать и изучить, но все это следует общей идее - \"все, что можно сделать в SQL, можно сделать и с помощью Active Record\". Кроме того, терминология остается той же, Active Record просто расширяет функциональность, предоставляя комплект универсальных методов (и концепций, таких как Relations), чтобы заодно сделаться еще более дружелюбным.  \r\n+\r\n+##Вы должны понимать:\r\n+\r\n+1. Что такое `ActiveRecord::Relation`?\r\n+2. Что значит \"ленивые (отложенные) вычисления\" (lazy evaluation)?\r\n+3. Как вычислить отношение (relation) внутри массива?\r\n+4. Как проверить, существует ли уже определенная запись в базе данных?\r\n+5. Чем полезно `#find_by` и как его использовать?\r\n+6. Какая разница между результатами, возвращаемыми с использованием запросов `#where` и `#find`?\r\n+7. Как объединять (join) таблицы в Rails?\r\n+8. Когда можно использовать символы / хэши, а когда необходимо использовать строковые переменные в явном виде (explicit strings) в качестве параметров запроса?\r\n+9. Что такое Скоупы (Scopes) и для чего они нужны?\r\n+10. Что должно произойти с методом класса, чтобы он действовал как скоуп (scope)?\r\n+\r\n+##Отношения и отложенные вычисления (Relations and Lazy Evaluation)\r\n+\r\n+Использование `User.find(1)` вернет совершенно определенный объект - пользователя с ID=1 в виде объекта Ruby. Однако, такое поведение не является обычным. Большинство запросов, на самом деле, возвращают не объект Ruby, а только его имитацию. Например:\r\n+\r\n+    User.where(:id => 1)\r\n+\r\n+Выглядит так, будто в результате был возвращен массив, содержащий в упорядоченном виде объекты User:\r\n+\r\n+    [#<User id: 1, email: \"foo@bar.com\">]\r\n+    \r\n+Но попробуйте выполнить `User.where(:id => 1).class` и увидите, что никакого массива (`Array`) нет, а есть экземпляр `ActiveRecord::Relation`. Отношения (relations) действительно очень похожи на массив, но представляют собой нечто большее.\r\n+\r\n+Запросы Active Record возвращают отложенные (ленивые) отношения (Relations). Собственно, нет никаких причин требовать от базы данных выполнить запрос до самой последней минуты. А что если вам, вообще, никогда не придется использовать этот запрос? Что если вы захотите усложнить его перед тем, как выполнить? Relations дают вам эту гибкость и позволяют более эффективно использовать драгоценное время вашей базы данных.\r\n+\r\n+Relations выполняются только тогда, когда становится совершенно необходимым узнать, что они содержат. Таким образом, если ваш контроллер захватывает (grab) 5 постов в блоге, используя `@posts = Post.limit(5)`, вашему взгляду предстает отношение (relation). И только когда код в представлении (in the view) вызывает метод `@posts` (например, `@posts.first.title`), запрос будет выполнен и отношение сохранено в памяти как реальный Ruby объект.\r\n+\r\n+Такое поведение сложно заметить, если вы пользуетесь для тестирования чем-то вроде Rails Console (`$ rails console`), потому что запросы будут запускаться прямо в консоли, т.к. она неявно запускает метод `.inspect` для отношения (relation), который в свою очередь требует выполнения запроса. Но попробуйте посоздавать запросы так, как мы делали выше, и попроверять их с помощью  `#class`... Чаще всего возвращаться будет `ActiveRecord::Relation`.\r\n+\r\n+##Цепочки запросов (Chaining Queries)\r\n+\r\n+Отношения (Relations) созданы для повышения не только скорости, но и гибкости. Допустим, вы хотите захватить (grab) первые 5 постов в виде упорядоченного в возрастающем порядке списка (`Post.limit(5).order(:created_at => :desc)`). Т.к. `#limit` возвращает отношение, `#order` берет это отношение и применяет к нему свои собственные критерии. Таким же образом вы можете соединить в цепочку десятки методов, и в итоге, когда приходит время для вычислений, ActiveRecord и SQL (если это то, что вы используете для своей базы данных) выдумывают оптимальный путь структурирования запросов, чтобы получить желаемый результат. \r\n+\r\n+Это именно то поведение, которое вы ожидаете, и отношения это то, что позволяет ему осуществиться.\r\n+\r\n+##Почему это важно?\r\n+\r\n+Тем, что запросы Active Records обычно возвращают отношения (Relations), стоит интересоватся хотя бы потому, что вам придется часто с этим сталкиваться при написании и отладке кода. Это знание поможет вам почувствовать себя увереннее, создавая цепочки методов, чтобы получить сложные запросы.\r\n+\r\n+Если вы придете к тому, что захотите, чтобы Отношение работало как массив, вы можете использовать `#to_a`, чтобы ускорить выполнение запроса.\r","path":"rails/19_active_record_queries.md","position":56,"original_position":56,"commit_id":"40ac9138bbcef4f5c60348ced8bccbe862beb9fb","original_commit_id":"40ac9138bbcef4f5c60348ced8bccbe862beb9fb","user":{"login":"iBublik","id":11278497,"avatar_url":"https://avatars.githubusercontent.com/u/11278497?v=3","gravatar_id":"","url":"https://api.github.com/users/iBublik","html_url":"https://github.com/iBublik","followers_url":"https://api.github.com/users/iBublik/followers","following_url":"https://api.github.com/users/iBublik/following{/other_user}","gists_url":"https://api.github.com/users/iBublik/gists{/gist_id}","starred_url":"https://api.github.com/users/iBublik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iBublik/subscriptions","organizations_url":"https://api.github.com/users/iBublik/orgs","repos_url":"https://api.github.com/users/iBublik/repos","events_url":"https://api.github.com/users/iBublik/events{/privacy}","received_events_url":"https://api.github.com/users/iBublik/received_events","type":"User","site_admin":false},"body":"Очень режет слух. Как вариант:\r\n*Если в конечном итоге вы захотите работать с отношением как с массивом, то можете использовать метод `#to_a`, чтобы также принудить его к выполнению запроса*\r\nКак минимум надо изменить часть *чтобы ускорить выполнение запроса*, потому что создается ложное впечатление, что от этого возрастет скорость выполнения запроса.","created_at":"2015-07-30T16:54:16Z","updated_at":"2015-07-30T16:54:16Z","html_url":"https://github.com/codenamecrud/curriculum/pull/70#discussion_r35892712","pull_request_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/70","_links":{"self":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/comments/35892712"},"html":{"href":"https://github.com/codenamecrud/curriculum/pull/70#discussion_r35892712"},"pull_request":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/70"}}},"pull_request":{"url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/70","id":41246284,"html_url":"https://github.com/codenamecrud/curriculum/pull/70","diff_url":"https://github.com/codenamecrud/curriculum/pull/70.diff","patch_url":"https://github.com/codenamecrud/curriculum/pull/70.patch","issue_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/70","number":70,"state":"open","locked":false,"title":"Active Record Queries","user":{"login":"Mirnais","id":13438595,"avatar_url":"https://avatars.githubusercontent.com/u/13438595?v=3","gravatar_id":"","url":"https://api.github.com/users/Mirnais","html_url":"https://github.com/Mirnais","followers_url":"https://api.github.com/users/Mirnais/followers","following_url":"https://api.github.com/users/Mirnais/following{/other_user}","gists_url":"https://api.github.com/users/Mirnais/gists{/gist_id}","starred_url":"https://api.github.com/users/Mirnais/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Mirnais/subscriptions","organizations_url":"https://api.github.com/users/Mirnais/orgs","repos_url":"https://api.github.com/users/Mirnais/repos","events_url":"https://api.github.com/users/Mirnais/events{/privacy}","received_events_url":"https://api.github.com/users/Mirnais/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-07-30T15:20:31Z","updated_at":"2015-07-30T16:54:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f82b4351797a96b5cdb1658ad9405e7530676d7e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/70/commits","review_comments_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/70/comments","review_comment_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/70/comments","statuses_url":"https://api.github.com/repos/codenamecrud/curriculum/statuses/40ac9138bbcef4f5c60348ced8bccbe862beb9fb","head":{"label":"codenamecrud:active-record-queries","ref":"active-record-queries","sha":"40ac9138bbcef4f5c60348ced8bccbe862beb9fb","user":{"login":"codenamecrud","id":11799719,"avatar_url":"https://avatars.githubusercontent.com/u/11799719?v=3","gravatar_id":"","url":"https://api.github.com/users/codenamecrud","html_url":"https://github.com/codenamecrud","followers_url":"https://api.github.com/users/codenamecrud/followers","following_url":"https://api.github.com/users/codenamecrud/following{/other_user}","gists_url":"https://api.github.com/users/codenamecrud/gists{/gist_id}","starred_url":"https://api.github.com/users/codenamecrud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenamecrud/subscriptions","organizations_url":"https://api.github.com/users/codenamecrud/orgs","repos_url":"https://api.github.com/users/codenamecrud/repos","events_url":"https://api.github.com/users/codenamecrud/events{/privacy}","received_events_url":"https://api.github.com/users/codenamecrud/received_events","type":"Organization","site_admin":false},"repo":{"id":33415384,"name":"curriculum","full_name":"codenamecrud/curriculum","owner":{"login":"codenamecrud","id":11799719,"avatar_url":"https://avatars.githubusercontent.com/u/11799719?v=3","gravatar_id":"","url":"https://api.github.com/users/codenamecrud","html_url":"https://github.com/codenamecrud","followers_url":"https://api.github.com/users/codenamecrud/followers","following_url":"https://api.github.com/users/codenamecrud/following{/other_user}","gists_url":"https://api.github.com/users/codenamecrud/gists{/gist_id}","starred_url":"https://api.github.com/users/codenamecrud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenamecrud/subscriptions","organizations_url":"https://api.github.com/users/codenamecrud/orgs","repos_url":"https://api.github.com/users/codenamecrud/repos","events_url":"https://api.github.com/users/codenamecrud/events{/privacy}","received_events_url":"https://api.github.com/users/codenamecrud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codenamecrud/curriculum","description":"Учебный план для codenamecrud.ru","fork":false,"url":"https://api.github.com/repos/codenamecrud/curriculum","forks_url":"https://api.github.com/repos/codenamecrud/curriculum/forks","keys_url":"https://api.github.com/repos/codenamecrud/curriculum/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codenamecrud/curriculum/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codenamecrud/curriculum/teams","hooks_url":"https://api.github.com/repos/codenamecrud/curriculum/hooks","issue_events_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/events{/number}","events_url":"https://api.github.com/repos/codenamecrud/curriculum/events","assignees_url":"https://api.github.com/repos/codenamecrud/curriculum/assignees{/user}","branches_url":"https://api.github.com/repos/codenamecrud/curriculum/branches{/branch}","tags_url":"https://api.github.com/repos/codenamecrud/curriculum/tags","blobs_url":"https://api.github.com/repos/codenamecrud/curriculum/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codenamecrud/curriculum/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codenamecrud/curriculum/git/refs{/sha}","trees_url":"https://api.github.com/repos/codenamecrud/curriculum/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codenamecrud/curriculum/statuses/{sha}","languages_url":"https://api.github.com/repos/codenamecrud/curriculum/languages","stargazers_url":"https://api.github.com/repos/codenamecrud/curriculum/stargazers","contributors_url":"https://api.github.com/repos/codenamecrud/curriculum/contributors","subscribers_url":"https://api.github.com/repos/codenamecrud/curriculum/subscribers","subscription_url":"https://api.github.com/repos/codenamecrud/curriculum/subscription","commits_url":"https://api.github.com/repos/codenamecrud/curriculum/commits{/sha}","git_commits_url":"https://api.github.com/repos/codenamecrud/curriculum/git/commits{/sha}","comments_url":"https://api.github.com/repos/codenamecrud/curriculum/comments{/number}","issue_comment_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/comments{/number}","contents_url":"https://api.github.com/repos/codenamecrud/curriculum/contents/{+path}","compare_url":"https://api.github.com/repos/codenamecrud/curriculum/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codenamecrud/curriculum/merges","archive_url":"https://api.github.com/repos/codenamecrud/curriculum/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codenamecrud/curriculum/downloads","issues_url":"https://api.github.com/repos/codenamecrud/curriculum/issues{/number}","pulls_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls{/number}","milestones_url":"https://api.github.com/repos/codenamecrud/curriculum/milestones{/number}","notifications_url":"https://api.github.com/repos/codenamecrud/curriculum/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codenamecrud/curriculum/labels{/name}","releases_url":"https://api.github.com/repos/codenamecrud/curriculum/releases{/id}","created_at":"2015-04-04T18:20:56Z","updated_at":"2015-07-29T17:38:37Z","pushed_at":"2015-07-30T15:20:31Z","git_url":"git://github.com/codenamecrud/curriculum.git","ssh_url":"git@github.com:codenamecrud/curriculum.git","clone_url":"https://github.com/codenamecrud/curriculum.git","svn_url":"https://github.com/codenamecrud/curriculum","homepage":"codenamecrud.ru","size":1536,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":2,"forks":3,"open_issues":2,"watchers":3,"default_branch":"master"}},"base":{"label":"codenamecrud:master","ref":"master","sha":"5e0c3a765eddad946cfc19ea3c494144ee6efb5b","user":{"login":"codenamecrud","id":11799719,"avatar_url":"https://avatars.githubusercontent.com/u/11799719?v=3","gravatar_id":"","url":"https://api.github.com/users/codenamecrud","html_url":"https://github.com/codenamecrud","followers_url":"https://api.github.com/users/codenamecrud/followers","following_url":"https://api.github.com/users/codenamecrud/following{/other_user}","gists_url":"https://api.github.com/users/codenamecrud/gists{/gist_id}","starred_url":"https://api.github.com/users/codenamecrud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenamecrud/subscriptions","organizations_url":"https://api.github.com/users/codenamecrud/orgs","repos_url":"https://api.github.com/users/codenamecrud/repos","events_url":"https://api.github.com/users/codenamecrud/events{/privacy}","received_events_url":"https://api.github.com/users/codenamecrud/received_events","type":"Organization","site_admin":false},"repo":{"id":33415384,"name":"curriculum","full_name":"codenamecrud/curriculum","owner":{"login":"codenamecrud","id":11799719,"avatar_url":"https://avatars.githubusercontent.com/u/11799719?v=3","gravatar_id":"","url":"https://api.github.com/users/codenamecrud","html_url":"https://github.com/codenamecrud","followers_url":"https://api.github.com/users/codenamecrud/followers","following_url":"https://api.github.com/users/codenamecrud/following{/other_user}","gists_url":"https://api.github.com/users/codenamecrud/gists{/gist_id}","starred_url":"https://api.github.com/users/codenamecrud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenamecrud/subscriptions","organizations_url":"https://api.github.com/users/codenamecrud/orgs","repos_url":"https://api.github.com/users/codenamecrud/repos","events_url":"https://api.github.com/users/codenamecrud/events{/privacy}","received_events_url":"https://api.github.com/users/codenamecrud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codenamecrud/curriculum","description":"Учебный план для codenamecrud.ru","fork":false,"url":"https://api.github.com/repos/codenamecrud/curriculum","forks_url":"https://api.github.com/repos/codenamecrud/curriculum/forks","keys_url":"https://api.github.com/repos/codenamecrud/curriculum/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codenamecrud/curriculum/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codenamecrud/curriculum/teams","hooks_url":"https://api.github.com/repos/codenamecrud/curriculum/hooks","issue_events_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/events{/number}","events_url":"https://api.github.com/repos/codenamecrud/curriculum/events","assignees_url":"https://api.github.com/repos/codenamecrud/curriculum/assignees{/user}","branches_url":"https://api.github.com/repos/codenamecrud/curriculum/branches{/branch}","tags_url":"https://api.github.com/repos/codenamecrud/curriculum/tags","blobs_url":"https://api.github.com/repos/codenamecrud/curriculum/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codenamecrud/curriculum/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codenamecrud/curriculum/git/refs{/sha}","trees_url":"https://api.github.com/repos/codenamecrud/curriculum/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codenamecrud/curriculum/statuses/{sha}","languages_url":"https://api.github.com/repos/codenamecrud/curriculum/languages","stargazers_url":"https://api.github.com/repos/codenamecrud/curriculum/stargazers","contributors_url":"https://api.github.com/repos/codenamecrud/curriculum/contributors","subscribers_url":"https://api.github.com/repos/codenamecrud/curriculum/subscribers","subscription_url":"https://api.github.com/repos/codenamecrud/curriculum/subscription","commits_url":"https://api.github.com/repos/codenamecrud/curriculum/commits{/sha}","git_commits_url":"https://api.github.com/repos/codenamecrud/curriculum/git/commits{/sha}","comments_url":"https://api.github.com/repos/codenamecrud/curriculum/comments{/number}","issue_comment_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/comments{/number}","contents_url":"https://api.github.com/repos/codenamecrud/curriculum/contents/{+path}","compare_url":"https://api.github.com/repos/codenamecrud/curriculum/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codenamecrud/curriculum/merges","archive_url":"https://api.github.com/repos/codenamecrud/curriculum/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codenamecrud/curriculum/downloads","issues_url":"https://api.github.com/repos/codenamecrud/curriculum/issues{/number}","pulls_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls{/number}","milestones_url":"https://api.github.com/repos/codenamecrud/curriculum/milestones{/number}","notifications_url":"https://api.github.com/repos/codenamecrud/curriculum/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codenamecrud/curriculum/labels{/name}","releases_url":"https://api.github.com/repos/codenamecrud/curriculum/releases{/id}","created_at":"2015-04-04T18:20:56Z","updated_at":"2015-07-29T17:38:37Z","pushed_at":"2015-07-30T15:20:31Z","git_url":"git://github.com/codenamecrud/curriculum.git","ssh_url":"git@github.com:codenamecrud/curriculum.git","clone_url":"https://github.com/codenamecrud/curriculum.git","svn_url":"https://github.com/codenamecrud/curriculum","homepage":"codenamecrud.ru","size":1536,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":2,"forks":3,"open_issues":2,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/70"},"html":{"href":"https://github.com/codenamecrud/curriculum/pull/70"},"issue":{"href":"https://api.github.com/repos/codenamecrud/curriculum/issues/70"},"comments":{"href":"https://api.github.com/repos/codenamecrud/curriculum/issues/70/comments"},"review_comments":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/70/comments"},"review_comment":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/70/commits"},"statuses":{"href":"https://api.github.com/repos/codenamecrud/curriculum/statuses/40ac9138bbcef4f5c60348ced8bccbe862beb9fb"}}}}