├── .tool-versions ├── README.md ├── chapter1 └── guesto │ ├── .browserslistrc │ ├── .gitignore │ ├── .ruby-version │ ├── .tool-versions │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ └── stylesheets │ │ │ ├── application.scss │ │ │ ├── greetings.scss │ │ │ └── scaffolds.scss │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ ├── controllers │ │ ├── application_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ └── greetings_controller.rb │ ├── helpers │ │ ├── application_helper.rb │ │ └── greetings_helper.rb │ ├── javascript │ │ ├── channels │ │ │ ├── consumer.js │ │ │ └── index.js │ │ └── packs │ │ │ └── application.js │ ├── jobs │ │ └── application_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ ├── concerns │ │ │ └── .keep │ │ └── greeting.rb │ └── views │ │ ├── greetings │ │ ├── _form.html.erb │ │ ├── _greeting.json.jbuilder │ │ ├── edit.html.erb │ │ ├── index.html.erb │ │ ├── index.json.jbuilder │ │ ├── new.html.erb │ │ ├── show.html.erb │ │ └── show.json.jbuilder │ │ └── layouts │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ └── mailer.text.erb │ ├── babel.config.js │ ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── webpack │ ├── webpack-dev-server │ └── yarn │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ ├── storage.yml │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── production.js │ │ └── test.js │ └── webpacker.yml │ ├── db │ ├── migrate │ │ └── 20200215071910_create_greetings.rb │ ├── schema.rb │ └── seeds.rb │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ └── .keep │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt │ ├── storage │ └── .keep │ ├── test │ ├── application_system_test_case.rb │ ├── channels │ │ └── application_cable │ │ │ └── connection_test.rb │ ├── controllers │ │ ├── .keep │ │ └── greetings_controller_test.rb │ ├── fixtures │ │ ├── .keep │ │ ├── files │ │ │ └── .keep │ │ └── greetings.yml │ ├── helpers │ │ └── .keep │ ├── integration │ │ └── .keep │ ├── mailers │ │ └── .keep │ ├── models │ │ ├── .keep │ │ └── greeting_test.rb │ ├── system │ │ ├── .keep │ │ └── greetings_test.rb │ └── test_helper.rb │ ├── tmp │ └── .keep │ ├── vendor │ └── .keep │ └── yarn.lock ├── chapter10 └── tandibi │ ├── .browserslistrc │ ├── .ebextensions │ ├── 02_nginx.config │ ├── 09_yarn_install.config │ └── container_commands.config │ ├── .ebignore │ ├── .gitignore │ ├── .rspec │ ├── .ruby-version │ ├── Dockerfile │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ └── stylesheets │ │ │ ├── application.css │ │ │ └── home.scss │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ ├── controllers │ │ ├── api │ │ │ └── v1 │ │ │ │ └── places_controller.rb │ │ ├── application_controller.rb │ │ ├── bonds_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── home_controller.rb │ │ ├── posts_controller.rb │ │ ├── settings │ │ │ └── users_controller.rb │ │ └── timelines_controller.rb │ ├── decorators │ │ ├── sight_decorator.rb │ │ └── user_decorator.rb │ ├── helpers │ │ ├── application_helper.rb │ │ ├── home_helper.rb │ │ ├── page_type_helper.rb │ │ ├── posts_helper.rb │ │ └── settings │ │ │ └── users_helper.rb │ ├── javascript │ │ ├── app.vue │ │ ├── channels │ │ │ ├── consumer.js │ │ │ └── index.js │ │ ├── components │ │ │ └── SightPoster │ │ │ │ ├── Map.vue │ │ │ │ ├── PlaceFinder.vue │ │ │ │ ├── PlaceList.vue │ │ │ │ └── index.vue │ │ ├── css │ │ │ ├── application.css │ │ │ ├── common.css │ │ │ ├── home.css │ │ │ ├── member.css │ │ │ ├── member │ │ │ │ ├── bonding_buttons.css │ │ │ │ ├── nav.css │ │ │ │ ├── poster.css │ │ │ │ ├── profile_header.css │ │ │ │ ├── settings.css │ │ │ │ ├── timeline.css │ │ │ │ └── users_list.css │ │ │ ├── modal.css │ │ │ ├── session.css │ │ │ └── tailwind.js │ │ ├── lib │ │ │ └── filters.js │ │ ├── packs │ │ │ ├── application.js │ │ │ ├── hello_vue.js │ │ │ ├── modal.js │ │ │ ├── timeline.js │ │ │ └── vue_application.js │ │ └── store │ │ │ ├── actions.js │ │ │ ├── index.js │ │ │ └── mutations.js │ ├── jobs │ │ ├── application_job.rb │ │ └── place_crawler_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ ├── bond.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── picture.rb │ │ ├── place.rb │ │ ├── post.rb │ │ ├── sight.rb │ │ ├── status.rb │ │ └── user.rb │ ├── rules │ │ └── user_rules.rb │ ├── serializers │ │ └── place_serializer.rb │ ├── services │ │ ├── application_service.rb │ │ ├── bond │ │ │ ├── acceptor.rb │ │ │ ├── follower.rb │ │ │ ├── rejector.rb │ │ │ └── unfollower.rb │ │ ├── place │ │ │ ├── crawler.rb │ │ │ └── finder.rb │ │ └── post │ │ │ ├── creator.rb │ │ │ └── picture_attacher.rb │ └── views │ │ ├── bonds │ │ ├── _bonding_buttons.html.erb │ │ ├── _users_list.html.erb │ │ ├── followers.html.erb │ │ └── following.html.erb │ │ ├── devise │ │ ├── confirmations │ │ │ └── new.html.erb │ │ ├── mailer │ │ │ ├── confirmation_instructions.html.erb │ │ │ ├── email_changed.html.erb │ │ │ ├── password_change.html.erb │ │ │ ├── reset_password_instructions.html.erb │ │ │ └── unlock_instructions.html.erb │ │ ├── passwords │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── registrations │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── sessions │ │ │ └── new.html.erb │ │ ├── shared │ │ │ ├── _error_messages.html.erb │ │ │ └── _links.html.erb │ │ └── unlocks │ │ │ └── new.html.erb │ │ ├── home │ │ ├── _action_button.html.erb │ │ └── index.html.erb │ │ ├── layouts │ │ ├── _alert.html.erb │ │ ├── _header.html.erb │ │ ├── _inside_modal.html.erb │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ ├── mailer.text.erb │ │ ├── member.html.erb │ │ ├── member │ │ │ └── _navbar.html.erb │ │ └── session.html.erb │ │ ├── posts │ │ ├── _form.html.erb │ │ └── show.html.erb │ │ ├── settings │ │ └── users │ │ │ ├── show.html.erb │ │ │ └── update.html.erb │ │ └── timelines │ │ ├── _all.html.erb │ │ ├── _line.html.erb │ │ ├── _profile_header.html.erb │ │ ├── _profile_stat.html.erb │ │ ├── index.html.erb │ │ ├── show.en-US.html.erb │ │ └── show.id.html.erb │ ├── babel.config.js │ ├── bin │ ├── bundle │ ├── delayed_job │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── webpack │ ├── webpack-dev-server │ └── yarn │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── devise.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ ├── devise.en-US.yml │ │ ├── en-US.yml │ │ ├── en.yml │ │ └── id.yml │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ ├── storage.yml │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── loaders │ │ │ └── vue.js │ │ ├── production.js │ │ └── test.js │ └── webpacker.yml │ ├── db │ ├── migrate │ │ ├── 20200224103334_create_users.rb │ │ ├── 20200224150609_create_bonds.rb │ │ ├── 20200224154526_create_posts.rb │ │ ├── 20200224224200_create_pictures.rb │ │ ├── 20200224230539_create_statuses.rb │ │ ├── 20200225013505_create_places.rb │ │ ├── 20200225083408_create_sights.rb │ │ ├── 20200315232037_add_devise_to_users.rb │ │ ├── 20200409212000_create_active_storage_tables.active_storage.rb │ │ ├── 20200412211317_create_delayed_jobs.rb │ │ └── 20200510232213_add_locale_to_users.rb │ ├── schema.rb │ └── seeds.rb │ ├── docker-compose.yml │ ├── docker-entrypoint.sh │ ├── lgtm.png │ ├── lgtm2.gif │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ ├── .keep │ │ └── auto_annotate_models.rake │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt │ ├── spec │ ├── decorators │ │ └── user_decorator_spec.rb │ ├── factories │ │ ├── bonds.rb │ │ ├── pictures.rb │ │ ├── places.rb │ │ ├── posts.rb │ │ ├── sights.rb │ │ ├── statuses.rb │ │ └── users.rb │ ├── features │ │ └── posting_spec.rb │ ├── fixtures │ │ └── vcr_cassettes │ │ │ └── api_v1_places_index_central_park.yml │ ├── helpers │ │ └── home_helper_spec.rb │ ├── jobs │ │ └── place_crawler_job_spec.rb │ ├── models │ │ ├── bond_spec.rb │ │ ├── picture_spec.rb │ │ ├── place_spec.rb │ │ ├── post_spec.rb │ │ ├── sight_spec.rb │ │ ├── status_spec.rb │ │ └── user_spec.rb │ ├── rails_helper.rb │ ├── requests │ │ ├── api │ │ │ └── v1 │ │ │ │ └── places_controller_spec.rb │ │ └── posts_controller_spec.rb │ ├── rules │ │ └── user_rules_spec.rb │ ├── services │ │ └── post │ │ │ └── creator_spec.rb │ ├── spec_helper.rb │ ├── support │ │ ├── api.rb │ │ ├── capybara.rb │ │ ├── devise.rb │ │ ├── factory_bot.rb │ │ ├── job.rb │ │ └── vcr.rb │ └── views │ │ ├── home │ │ └── index.html.erb_spec.rb │ │ └── timelines │ │ └── _line.html.erb_spec.rb │ ├── storage │ └── .keep │ ├── tmp │ └── .keep │ ├── vendor │ └── .keep │ └── yarn.lock ├── chapter3 └── coolprint │ ├── .tool-versions │ ├── Gemfile │ ├── Gemfile.lock │ └── app.rb ├── chapter4 └── tandibi │ ├── .browserslistrc │ ├── .gitignore │ ├── .rspec │ ├── .ruby-version │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ └── stylesheets │ │ │ └── application.css │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ ├── controllers │ │ ├── application_controller.rb │ │ └── concerns │ │ │ └── .keep │ ├── helpers │ │ └── application_helper.rb │ ├── javascript │ │ ├── channels │ │ │ ├── consumer.js │ │ │ └── index.js │ │ └── packs │ │ │ └── application.js │ ├── jobs │ │ └── application_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ ├── bond.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── picture.rb │ │ ├── place.rb │ │ ├── post.rb │ │ ├── sight.rb │ │ ├── status.rb │ │ └── user.rb │ └── views │ │ └── layouts │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ └── mailer.text.erb │ ├── babel.config.js │ ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── webpack │ ├── webpack-dev-server │ └── yarn │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ └── en.yml │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ ├── storage.yml │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── production.js │ │ └── test.js │ └── webpacker.yml │ ├── db │ ├── migrate │ │ ├── 20200224103334_create_users.rb │ │ ├── 20200224150609_create_bonds.rb │ │ ├── 20200224154526_create_posts.rb │ │ ├── 20200224224200_create_pictures.rb │ │ ├── 20200224230539_create_statuses.rb │ │ ├── 20200225013505_create_places.rb │ │ └── 20200225083408_create_sights.rb │ ├── schema.rb │ └── seeds.rb │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ ├── .keep │ │ └── auto_annotate_models.rake │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt │ ├── spec │ ├── factories │ │ ├── bonds.rb │ │ ├── pictures.rb │ │ ├── places.rb │ │ ├── posts.rb │ │ ├── sights.rb │ │ ├── statuses.rb │ │ └── users.rb │ ├── models │ │ ├── bond_spec.rb │ │ ├── picture_spec.rb │ │ ├── place_spec.rb │ │ ├── post_spec.rb │ │ ├── sight_spec.rb │ │ ├── status_spec.rb │ │ └── user_spec.rb │ ├── rails_helper.rb │ ├── spec_helper.rb │ └── support │ │ └── factory_bot.rb │ ├── storage │ └── .keep │ ├── tmp │ └── .keep │ ├── vendor │ └── .keep │ └── yarn.lock ├── chapter5 └── tandibi │ ├── .browserslistrc │ ├── .gitignore │ ├── .rspec │ ├── .ruby-version │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ └── stylesheets │ │ │ ├── application.css │ │ │ └── home.scss │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ ├── controllers │ │ ├── application_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ └── home_controller.rb │ ├── helpers │ │ ├── application_helper.rb │ │ └── home_helper.rb │ ├── javascript │ │ ├── channels │ │ │ ├── consumer.js │ │ │ └── index.js │ │ ├── css │ │ │ ├── application.css │ │ │ ├── common.css │ │ │ ├── home.css │ │ │ ├── session.css │ │ │ └── tailwind.js │ │ └── packs │ │ │ └── application.js │ ├── jobs │ │ └── application_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ ├── bond.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── picture.rb │ │ ├── place.rb │ │ ├── post.rb │ │ ├── sight.rb │ │ ├── status.rb │ │ └── user.rb │ └── views │ │ ├── devise │ │ ├── confirmations │ │ │ └── new.html.erb │ │ ├── mailer │ │ │ ├── confirmation_instructions.html.erb │ │ │ ├── email_changed.html.erb │ │ │ ├── password_change.html.erb │ │ │ ├── reset_password_instructions.html.erb │ │ │ └── unlock_instructions.html.erb │ │ ├── passwords │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── registrations │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── sessions │ │ │ └── new.html.erb │ │ ├── shared │ │ │ ├── _error_messages.html.erb │ │ │ └── _links.html.erb │ │ └── unlocks │ │ │ └── new.html.erb │ │ ├── home │ │ ├── _action_button.html.erb │ │ └── index.html.erb │ │ └── layouts │ │ ├── _alert.html.erb │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ ├── mailer.text.erb │ │ └── session.html.erb │ ├── babel.config.js │ ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── webpack │ ├── webpack-dev-server │ └── yarn │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── devise.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ ├── devise.en.yml │ │ └── en.yml │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ ├── storage.yml │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── production.js │ │ └── test.js │ └── webpacker.yml │ ├── db │ ├── migrate │ │ ├── 20200224103334_create_users.rb │ │ ├── 20200224150609_create_bonds.rb │ │ ├── 20200224154526_create_posts.rb │ │ ├── 20200224224200_create_pictures.rb │ │ ├── 20200224230539_create_statuses.rb │ │ ├── 20200225013505_create_places.rb │ │ ├── 20200225083408_create_sights.rb │ │ └── 20200315232037_add_devise_to_users.rb │ ├── schema.rb │ └── seeds.rb │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ ├── .keep │ │ └── auto_annotate_models.rake │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt │ ├── spec │ ├── factories │ │ ├── bonds.rb │ │ ├── pictures.rb │ │ ├── places.rb │ │ ├── posts.rb │ │ ├── sights.rb │ │ ├── statuses.rb │ │ └── users.rb │ ├── helpers │ │ └── home_helper_spec.rb │ ├── models │ │ ├── bond_spec.rb │ │ ├── picture_spec.rb │ │ ├── place_spec.rb │ │ ├── post_spec.rb │ │ ├── sight_spec.rb │ │ ├── status_spec.rb │ │ └── user_spec.rb │ ├── rails_helper.rb │ ├── spec_helper.rb │ ├── support │ │ └── factory_bot.rb │ └── views │ │ └── home │ │ └── index.html.erb_spec.rb │ ├── storage │ └── .keep │ ├── tmp │ └── .keep │ ├── vendor │ └── .keep │ └── yarn.lock ├── chapter6 └── tandibi │ ├── .browserslistrc │ ├── .gitignore │ ├── .rspec │ ├── .ruby-version │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ └── stylesheets │ │ │ ├── application.css │ │ │ └── home.scss │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ ├── controllers │ │ ├── application_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── home_controller.rb │ │ ├── posts_controller.rb │ │ └── timelines_controller.rb │ ├── decorators │ │ ├── sight_decorator.rb │ │ └── user_decorator.rb │ ├── helpers │ │ ├── application_helper.rb │ │ ├── home_helper.rb │ │ ├── posts_helper.rb │ │ └── timelines_helper.rb │ ├── javascript │ │ ├── channels │ │ │ ├── consumer.js │ │ │ └── index.js │ │ ├── css │ │ │ ├── application.css │ │ │ ├── common.css │ │ │ ├── home.css │ │ │ ├── member.css │ │ │ ├── member │ │ │ │ ├── nav.css │ │ │ │ ├── poster.css │ │ │ │ └── timeline.css │ │ │ ├── modal.css │ │ │ ├── session.css │ │ │ └── tailwind.js │ │ └── packs │ │ │ ├── application.js │ │ │ ├── modal.js │ │ │ └── timeline.js │ ├── jobs │ │ └── application_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ ├── bond.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── picture.rb │ │ ├── place.rb │ │ ├── post.rb │ │ ├── sight.rb │ │ ├── status.rb │ │ └── user.rb │ ├── services │ │ ├── application_service.rb │ │ └── post │ │ │ └── creator.rb │ └── views │ │ ├── devise │ │ ├── confirmations │ │ │ └── new.html.erb │ │ ├── mailer │ │ │ ├── confirmation_instructions.html.erb │ │ │ ├── email_changed.html.erb │ │ │ ├── password_change.html.erb │ │ │ ├── reset_password_instructions.html.erb │ │ │ └── unlock_instructions.html.erb │ │ ├── passwords │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── registrations │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── sessions │ │ │ └── new.html.erb │ │ ├── shared │ │ │ ├── _error_messages.html.erb │ │ │ └── _links.html.erb │ │ └── unlocks │ │ │ └── new.html.erb │ │ ├── home │ │ ├── _action_button.html.erb │ │ └── index.html.erb │ │ ├── layouts │ │ ├── _alert.html.erb │ │ ├── _header.html.erb │ │ ├── _inside_modal.html.erb │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ ├── mailer.text.erb │ │ ├── member.html.erb │ │ ├── member │ │ │ └── _navbar.html.erb │ │ └── session.html.erb │ │ ├── posts │ │ ├── _form.html.erb │ │ └── show.html.erb │ │ └── timelines │ │ ├── _all.html.erb │ │ ├── _line.html.erb │ │ ├── index.html.erb │ │ └── show.html.erb │ ├── babel.config.js │ ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── webpack │ ├── webpack-dev-server │ └── yarn │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── devise.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ ├── devise.en.yml │ │ └── en.yml │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ ├── storage.yml │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── production.js │ │ └── test.js │ └── webpacker.yml │ ├── db │ ├── migrate │ │ ├── 20200224103334_create_users.rb │ │ ├── 20200224150609_create_bonds.rb │ │ ├── 20200224154526_create_posts.rb │ │ ├── 20200224224200_create_pictures.rb │ │ ├── 20200224230539_create_statuses.rb │ │ ├── 20200225013505_create_places.rb │ │ ├── 20200225083408_create_sights.rb │ │ └── 20200315232037_add_devise_to_users.rb │ ├── schema.rb │ └── seeds.rb │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ ├── .keep │ │ └── auto_annotate_models.rake │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt │ ├── spec │ ├── decorators │ │ └── user_decorator_spec.rb │ ├── factories │ │ ├── bonds.rb │ │ ├── pictures.rb │ │ ├── places.rb │ │ ├── posts.rb │ │ ├── sights.rb │ │ ├── statuses.rb │ │ └── users.rb │ ├── helpers │ │ └── home_helper_spec.rb │ ├── models │ │ ├── bond_spec.rb │ │ ├── picture_spec.rb │ │ ├── place_spec.rb │ │ ├── post_spec.rb │ │ ├── sight_spec.rb │ │ ├── status_spec.rb │ │ └── user_spec.rb │ ├── rails_helper.rb │ ├── requests │ │ └── posts_controller_spec.rb │ ├── services │ │ └── post │ │ │ └── creator_spec.rb │ ├── spec_helper.rb │ ├── support │ │ ├── devise.rb │ │ └── factory_bot.rb │ └── views │ │ ├── home │ │ └── index.html.erb_spec.rb │ │ └── timelines │ │ └── _line.html.erb_spec.rb │ ├── storage │ └── .keep │ ├── tmp │ └── .keep │ ├── vendor │ └── .keep │ └── yarn.lock ├── chapter7 └── tandibi │ ├── .browserslistrc │ ├── .gitignore │ ├── .rspec │ ├── .ruby-version │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ └── stylesheets │ │ │ ├── application.css │ │ │ └── home.scss │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ ├── controllers │ │ ├── application_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── home_controller.rb │ │ ├── posts_controller.rb │ │ └── timelines_controller.rb │ ├── decorators │ │ ├── sight_decorator.rb │ │ └── user_decorator.rb │ ├── helpers │ │ ├── application_helper.rb │ │ ├── home_helper.rb │ │ ├── posts_helper.rb │ │ └── timelines_helper.rb │ ├── javascript │ │ ├── channels │ │ │ ├── consumer.js │ │ │ └── index.js │ │ ├── css │ │ │ ├── application.css │ │ │ ├── common.css │ │ │ ├── home.css │ │ │ ├── member.css │ │ │ ├── member │ │ │ │ ├── nav.css │ │ │ │ ├── poster.css │ │ │ │ └── timeline.css │ │ │ ├── modal.css │ │ │ ├── session.css │ │ │ └── tailwind.js │ │ └── packs │ │ │ ├── application.js │ │ │ ├── modal.js │ │ │ └── timeline.js │ ├── jobs │ │ └── application_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ ├── bond.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── picture.rb │ │ ├── place.rb │ │ ├── post.rb │ │ ├── sight.rb │ │ ├── status.rb │ │ └── user.rb │ ├── services │ │ ├── application_service.rb │ │ └── post │ │ │ ├── creator.rb │ │ │ └── picture_attacher.rb │ └── views │ │ ├── devise │ │ ├── confirmations │ │ │ └── new.html.erb │ │ ├── mailer │ │ │ ├── confirmation_instructions.html.erb │ │ │ ├── email_changed.html.erb │ │ │ ├── password_change.html.erb │ │ │ ├── reset_password_instructions.html.erb │ │ │ └── unlock_instructions.html.erb │ │ ├── passwords │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── registrations │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── sessions │ │ │ └── new.html.erb │ │ ├── shared │ │ │ ├── _error_messages.html.erb │ │ │ └── _links.html.erb │ │ └── unlocks │ │ │ └── new.html.erb │ │ ├── home │ │ ├── _action_button.html.erb │ │ └── index.html.erb │ │ ├── layouts │ │ ├── _alert.html.erb │ │ ├── _header.html.erb │ │ ├── _inside_modal.html.erb │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ ├── mailer.text.erb │ │ ├── member.html.erb │ │ ├── member │ │ │ └── _navbar.html.erb │ │ └── session.html.erb │ │ ├── posts │ │ ├── _form.html.erb │ │ └── show.html.erb │ │ └── timelines │ │ ├── _all.html.erb │ │ ├── _line.html.erb │ │ ├── index.html.erb │ │ └── show.html.erb │ ├── babel.config.js │ ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── webpack │ ├── webpack-dev-server │ └── yarn │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── devise.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ ├── devise.en.yml │ │ └── en.yml │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ ├── storage.yml │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── production.js │ │ └── test.js │ └── webpacker.yml │ ├── db │ ├── migrate │ │ ├── 20200224103334_create_users.rb │ │ ├── 20200224150609_create_bonds.rb │ │ ├── 20200224154526_create_posts.rb │ │ ├── 20200224224200_create_pictures.rb │ │ ├── 20200224230539_create_statuses.rb │ │ ├── 20200225013505_create_places.rb │ │ ├── 20200225083408_create_sights.rb │ │ ├── 20200315232037_add_devise_to_users.rb │ │ └── 20200409212000_create_active_storage_tables.active_storage.rb │ ├── schema.rb │ └── seeds.rb │ ├── lgtm.png │ ├── lgtm2.gif │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ ├── .keep │ │ └── auto_annotate_models.rake │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt │ ├── spec │ ├── decorators │ │ └── user_decorator_spec.rb │ ├── factories │ │ ├── bonds.rb │ │ ├── pictures.rb │ │ ├── places.rb │ │ ├── posts.rb │ │ ├── sights.rb │ │ ├── statuses.rb │ │ └── users.rb │ ├── features │ │ └── posting_spec.rb │ ├── helpers │ │ └── home_helper_spec.rb │ ├── models │ │ ├── bond_spec.rb │ │ ├── picture_spec.rb │ │ ├── place_spec.rb │ │ ├── post_spec.rb │ │ ├── sight_spec.rb │ │ ├── status_spec.rb │ │ └── user_spec.rb │ ├── rails_helper.rb │ ├── requests │ │ └── posts_controller_spec.rb │ ├── services │ │ └── post │ │ │ └── creator_spec.rb │ ├── spec_helper.rb │ ├── support │ │ ├── capybara.rb │ │ ├── devise.rb │ │ └── factory_bot.rb │ └── views │ │ ├── home │ │ └── index.html.erb_spec.rb │ │ └── timelines │ │ └── _line.html.erb_spec.rb │ ├── storage │ └── .keep │ ├── tmp │ └── .keep │ ├── vendor │ └── .keep │ └── yarn.lock ├── chapter8 └── tandibi │ ├── .browserslistrc │ ├── .gitignore │ ├── .rspec │ ├── .ruby-version │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ └── stylesheets │ │ │ ├── application.css │ │ │ └── home.scss │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ ├── controllers │ │ ├── api │ │ │ └── v1 │ │ │ │ └── places_controller.rb │ │ ├── application_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── home_controller.rb │ │ ├── posts_controller.rb │ │ └── timelines_controller.rb │ ├── decorators │ │ ├── sight_decorator.rb │ │ └── user_decorator.rb │ ├── helpers │ │ ├── application_helper.rb │ │ ├── home_helper.rb │ │ ├── posts_helper.rb │ │ └── timelines_helper.rb │ ├── javascript │ │ ├── app.vue │ │ ├── channels │ │ │ ├── consumer.js │ │ │ └── index.js │ │ ├── components │ │ │ └── SightPoster │ │ │ │ ├── Map.vue │ │ │ │ ├── PlaceFinder.vue │ │ │ │ ├── PlaceList.vue │ │ │ │ └── index.vue │ │ ├── css │ │ │ ├── application.css │ │ │ ├── common.css │ │ │ ├── home.css │ │ │ ├── member.css │ │ │ ├── member │ │ │ │ ├── nav.css │ │ │ │ ├── poster.css │ │ │ │ └── timeline.css │ │ │ ├── modal.css │ │ │ ├── session.css │ │ │ └── tailwind.js │ │ ├── lib │ │ │ └── filters.js │ │ ├── packs │ │ │ ├── application.js │ │ │ ├── hello_vue.js │ │ │ ├── modal.js │ │ │ ├── timeline.js │ │ │ └── vue_application.js │ │ └── store │ │ │ ├── actions.js │ │ │ ├── index.js │ │ │ └── mutations.js │ ├── jobs │ │ ├── application_job.rb │ │ └── place_crawler_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ ├── bond.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── picture.rb │ │ ├── place.rb │ │ ├── post.rb │ │ ├── sight.rb │ │ ├── status.rb │ │ └── user.rb │ ├── serializers │ │ └── place_serializer.rb │ ├── services │ │ ├── application_service.rb │ │ ├── place │ │ │ ├── crawler.rb │ │ │ └── finder.rb │ │ └── post │ │ │ ├── creator.rb │ │ │ └── picture_attacher.rb │ └── views │ │ ├── devise │ │ ├── confirmations │ │ │ └── new.html.erb │ │ ├── mailer │ │ │ ├── confirmation_instructions.html.erb │ │ │ ├── email_changed.html.erb │ │ │ ├── password_change.html.erb │ │ │ ├── reset_password_instructions.html.erb │ │ │ └── unlock_instructions.html.erb │ │ ├── passwords │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── registrations │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── sessions │ │ │ └── new.html.erb │ │ ├── shared │ │ │ ├── _error_messages.html.erb │ │ │ └── _links.html.erb │ │ └── unlocks │ │ │ └── new.html.erb │ │ ├── home │ │ ├── _action_button.html.erb │ │ └── index.html.erb │ │ ├── layouts │ │ ├── _alert.html.erb │ │ ├── _header.html.erb │ │ ├── _inside_modal.html.erb │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ ├── mailer.text.erb │ │ ├── member.html.erb │ │ ├── member │ │ │ └── _navbar.html.erb │ │ └── session.html.erb │ │ ├── posts │ │ ├── _form.html.erb │ │ └── show.html.erb │ │ └── timelines │ │ ├── _all.html.erb │ │ ├── _line.html.erb │ │ ├── index.html.erb │ │ └── show.html.erb │ ├── babel.config.js │ ├── bin │ ├── bundle │ ├── delayed_job │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── webpack │ ├── webpack-dev-server │ └── yarn │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── devise.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ ├── devise.en.yml │ │ └── en.yml │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ ├── storage.yml │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── loaders │ │ │ └── vue.js │ │ ├── production.js │ │ └── test.js │ └── webpacker.yml │ ├── db │ ├── migrate │ │ ├── 20200224103334_create_users.rb │ │ ├── 20200224150609_create_bonds.rb │ │ ├── 20200224154526_create_posts.rb │ │ ├── 20200224224200_create_pictures.rb │ │ ├── 20200224230539_create_statuses.rb │ │ ├── 20200225013505_create_places.rb │ │ ├── 20200225083408_create_sights.rb │ │ ├── 20200315232037_add_devise_to_users.rb │ │ ├── 20200409212000_create_active_storage_tables.active_storage.rb │ │ └── 20200412211317_create_delayed_jobs.rb │ ├── schema.rb │ └── seeds.rb │ ├── lgtm.png │ ├── lgtm2.gif │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ ├── .keep │ │ └── auto_annotate_models.rake │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt │ ├── spec │ ├── decorators │ │ └── user_decorator_spec.rb │ ├── factories │ │ ├── bonds.rb │ │ ├── pictures.rb │ │ ├── places.rb │ │ ├── posts.rb │ │ ├── sights.rb │ │ ├── statuses.rb │ │ └── users.rb │ ├── features │ │ └── posting_spec.rb │ ├── fixtures │ │ └── vcr_cassettes │ │ │ └── api_v1_places_index_central_park.yml │ ├── helpers │ │ └── home_helper_spec.rb │ ├── jobs │ │ └── place_crawler_job_spec.rb │ ├── models │ │ ├── bond_spec.rb │ │ ├── picture_spec.rb │ │ ├── place_spec.rb │ │ ├── post_spec.rb │ │ ├── sight_spec.rb │ │ ├── status_spec.rb │ │ └── user_spec.rb │ ├── rails_helper.rb │ ├── requests │ │ ├── api │ │ │ └── v1 │ │ │ │ └── places_controller_spec.rb │ │ └── posts_controller_spec.rb │ ├── services │ │ └── post │ │ │ └── creator_spec.rb │ ├── spec_helper.rb │ ├── support │ │ ├── api.rb │ │ ├── capybara.rb │ │ ├── devise.rb │ │ ├── factory_bot.rb │ │ ├── job.rb │ │ └── vcr.rb │ └── views │ │ ├── home │ │ └── index.html.erb_spec.rb │ │ └── timelines │ │ └── _line.html.erb_spec.rb │ ├── storage │ └── .keep │ ├── tmp │ └── .keep │ ├── vendor │ └── .keep │ └── yarn.lock ├── chapter9 └── tandibi │ ├── .browserslistrc │ ├── .gitignore │ ├── .rspec │ ├── .ruby-version │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── Rakefile │ ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ └── stylesheets │ │ │ ├── application.css │ │ │ └── home.scss │ ├── channels │ │ └── application_cable │ │ │ ├── channel.rb │ │ │ └── connection.rb │ ├── controllers │ │ ├── api │ │ │ └── v1 │ │ │ │ └── places_controller.rb │ │ ├── application_controller.rb │ │ ├── bonds_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── home_controller.rb │ │ ├── posts_controller.rb │ │ ├── settings │ │ │ └── users_controller.rb │ │ └── timelines_controller.rb │ ├── decorators │ │ ├── sight_decorator.rb │ │ └── user_decorator.rb │ ├── helpers │ │ ├── application_helper.rb │ │ ├── home_helper.rb │ │ ├── page_type_helper.rb │ │ ├── posts_helper.rb │ │ └── settings │ │ │ └── users_helper.rb │ ├── javascript │ │ ├── app.vue │ │ ├── channels │ │ │ ├── consumer.js │ │ │ └── index.js │ │ ├── components │ │ │ └── SightPoster │ │ │ │ ├── Map.vue │ │ │ │ ├── PlaceFinder.vue │ │ │ │ ├── PlaceList.vue │ │ │ │ └── index.vue │ │ ├── css │ │ │ ├── application.css │ │ │ ├── common.css │ │ │ ├── home.css │ │ │ ├── member.css │ │ │ ├── member │ │ │ │ ├── bonding_buttons.css │ │ │ │ ├── nav.css │ │ │ │ ├── poster.css │ │ │ │ ├── profile_header.css │ │ │ │ ├── settings.css │ │ │ │ ├── timeline.css │ │ │ │ └── users_list.css │ │ │ ├── modal.css │ │ │ ├── session.css │ │ │ └── tailwind.js │ │ ├── lib │ │ │ └── filters.js │ │ ├── packs │ │ │ ├── application.js │ │ │ ├── hello_vue.js │ │ │ ├── modal.js │ │ │ ├── timeline.js │ │ │ └── vue_application.js │ │ └── store │ │ │ ├── actions.js │ │ │ ├── index.js │ │ │ └── mutations.js │ ├── jobs │ │ ├── application_job.rb │ │ └── place_crawler_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ ├── bond.rb │ │ ├── concerns │ │ │ └── .keep │ │ ├── picture.rb │ │ ├── place.rb │ │ ├── post.rb │ │ ├── sight.rb │ │ ├── status.rb │ │ └── user.rb │ ├── rules │ │ └── user_rules.rb │ ├── serializers │ │ └── place_serializer.rb │ ├── services │ │ ├── application_service.rb │ │ ├── bond │ │ │ ├── acceptor.rb │ │ │ ├── follower.rb │ │ │ ├── rejector.rb │ │ │ └── unfollower.rb │ │ ├── place │ │ │ ├── crawler.rb │ │ │ └── finder.rb │ │ └── post │ │ │ ├── creator.rb │ │ │ └── picture_attacher.rb │ └── views │ │ ├── bonds │ │ ├── _bonding_buttons.html.erb │ │ ├── _users_list.html.erb │ │ ├── followers.html.erb │ │ └── following.html.erb │ │ ├── devise │ │ ├── confirmations │ │ │ └── new.html.erb │ │ ├── mailer │ │ │ ├── confirmation_instructions.html.erb │ │ │ ├── email_changed.html.erb │ │ │ ├── password_change.html.erb │ │ │ ├── reset_password_instructions.html.erb │ │ │ └── unlock_instructions.html.erb │ │ ├── passwords │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── registrations │ │ │ ├── edit.html.erb │ │ │ └── new.html.erb │ │ ├── sessions │ │ │ └── new.html.erb │ │ ├── shared │ │ │ ├── _error_messages.html.erb │ │ │ └── _links.html.erb │ │ └── unlocks │ │ │ └── new.html.erb │ │ ├── home │ │ ├── _action_button.html.erb │ │ └── index.html.erb │ │ ├── layouts │ │ ├── _alert.html.erb │ │ ├── _header.html.erb │ │ ├── _inside_modal.html.erb │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ ├── mailer.text.erb │ │ ├── member.html.erb │ │ ├── member │ │ │ └── _navbar.html.erb │ │ └── session.html.erb │ │ ├── posts │ │ ├── _form.html.erb │ │ └── show.html.erb │ │ ├── settings │ │ └── users │ │ │ ├── show.html.erb │ │ │ └── update.html.erb │ │ └── timelines │ │ ├── _all.html.erb │ │ ├── _line.html.erb │ │ ├── _profile_header.html.erb │ │ ├── _profile_stat.html.erb │ │ ├── index.html.erb │ │ └── show.html.erb │ ├── babel.config.js │ ├── bin │ ├── bundle │ ├── delayed_job │ ├── rails │ ├── rake │ ├── setup │ ├── spring │ ├── webpack │ ├── webpack-dev-server │ └── yarn │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── cookies_serializer.rb │ │ ├── devise.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ └── wrap_parameters.rb │ ├── locales │ │ ├── devise.en.yml │ │ └── en.yml │ ├── puma.rb │ ├── routes.rb │ ├── spring.rb │ ├── storage.yml │ ├── webpack │ │ ├── development.js │ │ ├── environment.js │ │ ├── loaders │ │ │ └── vue.js │ │ ├── production.js │ │ └── test.js │ └── webpacker.yml │ ├── db │ ├── migrate │ │ ├── 20200224103334_create_users.rb │ │ ├── 20200224150609_create_bonds.rb │ │ ├── 20200224154526_create_posts.rb │ │ ├── 20200224224200_create_pictures.rb │ │ ├── 20200224230539_create_statuses.rb │ │ ├── 20200225013505_create_places.rb │ │ ├── 20200225083408_create_sights.rb │ │ ├── 20200315232037_add_devise_to_users.rb │ │ ├── 20200409212000_create_active_storage_tables.active_storage.rb │ │ └── 20200412211317_create_delayed_jobs.rb │ ├── schema.rb │ └── seeds.rb │ ├── lgtm.png │ ├── lgtm2.gif │ ├── lib │ ├── assets │ │ └── .keep │ └── tasks │ │ ├── .keep │ │ └── auto_annotate_models.rake │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.js │ ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt │ ├── spec │ ├── decorators │ │ └── user_decorator_spec.rb │ ├── factories │ │ ├── bonds.rb │ │ ├── pictures.rb │ │ ├── places.rb │ │ ├── posts.rb │ │ ├── sights.rb │ │ ├── statuses.rb │ │ └── users.rb │ ├── features │ │ └── posting_spec.rb │ ├── fixtures │ │ └── vcr_cassettes │ │ │ └── api_v1_places_index_central_park.yml │ ├── helpers │ │ └── home_helper_spec.rb │ ├── jobs │ │ └── place_crawler_job_spec.rb │ ├── models │ │ ├── bond_spec.rb │ │ ├── picture_spec.rb │ │ ├── place_spec.rb │ │ ├── post_spec.rb │ │ ├── sight_spec.rb │ │ ├── status_spec.rb │ │ └── user_spec.rb │ ├── rails_helper.rb │ ├── requests │ │ ├── api │ │ │ └── v1 │ │ │ │ └── places_controller_spec.rb │ │ └── posts_controller_spec.rb │ ├── rules │ │ └── user_rules_spec.rb │ ├── services │ │ └── post │ │ │ └── creator_spec.rb │ ├── spec_helper.rb │ ├── support │ │ ├── api.rb │ │ ├── capybara.rb │ │ ├── devise.rb │ │ ├── factory_bot.rb │ │ ├── job.rb │ │ └── vcr.rb │ └── views │ │ ├── home │ │ └── index.html.erb_spec.rb │ │ └── timelines │ │ └── _line.html.erb_spec.rb │ ├── storage │ └── .keep │ ├── tmp │ └── .keep │ ├── vendor │ └── .keep │ └── yarn.lock └── meta └── bookcover.jpg /.tool-versions: -------------------------------------------------------------------------------- 1 | ruby 2.6.5 2 | -------------------------------------------------------------------------------- /chapter1/guesto/.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /chapter1/guesto/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.7.0 2 | -------------------------------------------------------------------------------- /chapter1/guesto/.tool-versions: -------------------------------------------------------------------------------- 1 | ruby 2.6.5 2 | -------------------------------------------------------------------------------- /chapter1/guesto/README.md: -------------------------------------------------------------------------------- 1 | # Guesto 2 | 3 | A guestbook app 4 | -------------------------------------------------------------------------------- /chapter1/guesto/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /chapter1/guesto/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /chapter1/guesto/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/app/assets/images/.keep -------------------------------------------------------------------------------- /chapter1/guesto/app/assets/stylesheets/greetings.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Greetings controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: https://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /chapter1/guesto/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter1/guesto/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter1/guesto/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | end 3 | -------------------------------------------------------------------------------- /chapter1/guesto/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /chapter1/guesto/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter1/guesto/app/helpers/greetings_helper.rb: -------------------------------------------------------------------------------- 1 | module GreetingsHelper 2 | def gravatarized_url(name) 3 | hash = Digest::MD5.hexdigest(name) 4 | "https://www.gravatar.com/avatar/#{hash}?d=wavatar" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /chapter1/guesto/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /chapter1/guesto/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /chapter1/guesto/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /chapter1/guesto/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /chapter1/guesto/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /chapter1/guesto/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/app/models/concerns/.keep -------------------------------------------------------------------------------- /chapter1/guesto/app/models/greeting.rb: -------------------------------------------------------------------------------- 1 | class Greeting < ApplicationRecord 2 | validates :name, presence: true 3 | validates :message, presence: true 4 | end 5 | -------------------------------------------------------------------------------- /chapter1/guesto/app/views/greetings/_greeting.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! greeting, :id, :name, :message, :created_at, :updated_at 2 | json.url greeting_url(greeting, format: :json) 3 | -------------------------------------------------------------------------------- /chapter1/guesto/app/views/greetings/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Greeting

2 | 3 | <%= render 'form', greeting: @greeting %> 4 | 5 | <%= link_to 'Show', @greeting %> | 6 | <%= link_to 'Back', greetings_path %> 7 | -------------------------------------------------------------------------------- /chapter1/guesto/app/views/greetings/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @greetings, partial: "greetings/greeting", as: :greeting 2 | -------------------------------------------------------------------------------- /chapter1/guesto/app/views/greetings/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Greeting

2 | 3 | <%= render 'form', greeting: @greeting %> 4 | 5 | <%= link_to 'Back', greetings_path %> 6 | -------------------------------------------------------------------------------- /chapter1/guesto/app/views/greetings/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Name: 5 | <%= @greeting.name %> 6 |

7 | 8 |

9 | Message: 10 | <%= @greeting.message %> 11 |

12 | 13 | <%= link_to 'Edit', edit_greeting_path(@greeting) %> | 14 | <%= link_to 'Back', greetings_path %> 15 | -------------------------------------------------------------------------------- /chapter1/guesto/app/views/greetings/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "greetings/greeting", greeting: @greeting 2 | -------------------------------------------------------------------------------- /chapter1/guesto/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /chapter1/guesto/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /chapter1/guesto/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /chapter1/guesto/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /chapter1/guesto/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /chapter1/guesto/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /chapter1/guesto/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /chapter1/guesto/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: guesto_production 11 | -------------------------------------------------------------------------------- /chapter1/guesto/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /chapter1/guesto/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /chapter1/guesto/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /chapter1/guesto/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /chapter1/guesto/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /chapter1/guesto/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root to: "greetings#index" 3 | resources :greetings 4 | # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 5 | end 6 | -------------------------------------------------------------------------------- /chapter1/guesto/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /chapter1/guesto/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter1/guesto/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | module.exports = environment 4 | -------------------------------------------------------------------------------- /chapter1/guesto/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter1/guesto/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter1/guesto/db/migrate/20200215071910_create_greetings.rb: -------------------------------------------------------------------------------- 1 | class CreateGreetings < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :greetings do |t| 4 | t.string :name 5 | t.text :message 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter1/guesto/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) 7 | # Character.create(name: 'Luke', movie: movies.first) 8 | -------------------------------------------------------------------------------- /chapter1/guesto/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/lib/assets/.keep -------------------------------------------------------------------------------- /chapter1/guesto/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/lib/tasks/.keep -------------------------------------------------------------------------------- /chapter1/guesto/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/log/.keep -------------------------------------------------------------------------------- /chapter1/guesto/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "guesto", 3 | "private": true, 4 | "dependencies": { 5 | "@rails/actioncable": "^6.0.0", 6 | "@rails/activestorage": "^6.0.0", 7 | "@rails/ujs": "^6.0.0", 8 | "@rails/webpacker": "4.2.2", 9 | "turbolinks": "^5.2.0" 10 | }, 11 | "version": "0.1.0", 12 | "devDependencies": { 13 | "webpack-dev-server": "^3.10.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /chapter1/guesto/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('postcss-preset-env')({ 6 | autoprefixer: { 7 | flexbox: 'no-2009' 8 | }, 9 | stage: 3 10 | }) 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /chapter1/guesto/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /chapter1/guesto/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/public/apple-touch-icon.png -------------------------------------------------------------------------------- /chapter1/guesto/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/public/favicon.ico -------------------------------------------------------------------------------- /chapter1/guesto/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /chapter1/guesto/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/storage/.keep -------------------------------------------------------------------------------- /chapter1/guesto/test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 4 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400] 5 | end 6 | -------------------------------------------------------------------------------- /chapter1/guesto/test/channels/application_cable/connection_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase 4 | # test "connects with cookies" do 5 | # cookies.signed[:user_id] = 42 6 | # 7 | # connect 8 | # 9 | # assert_equal connection.user_id, "42" 10 | # end 11 | end 12 | -------------------------------------------------------------------------------- /chapter1/guesto/test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/test/controllers/.keep -------------------------------------------------------------------------------- /chapter1/guesto/test/fixtures/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/test/fixtures/.keep -------------------------------------------------------------------------------- /chapter1/guesto/test/fixtures/files/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/test/fixtures/files/.keep -------------------------------------------------------------------------------- /chapter1/guesto/test/fixtures/greetings.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: MyString 5 | message: MyText 6 | 7 | two: 8 | name: MyString 9 | message: MyText 10 | -------------------------------------------------------------------------------- /chapter1/guesto/test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/test/helpers/.keep -------------------------------------------------------------------------------- /chapter1/guesto/test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/test/integration/.keep -------------------------------------------------------------------------------- /chapter1/guesto/test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/test/mailers/.keep -------------------------------------------------------------------------------- /chapter1/guesto/test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/test/models/.keep -------------------------------------------------------------------------------- /chapter1/guesto/test/models/greeting_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class GreetingTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /chapter1/guesto/test/system/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/test/system/.keep -------------------------------------------------------------------------------- /chapter1/guesto/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/tmp/.keep -------------------------------------------------------------------------------- /chapter1/guesto/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter1/guesto/vendor/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /chapter10/tandibi/.ebextensions/container_commands.config: -------------------------------------------------------------------------------- 1 | container_commands: 2 | 01_set_tmp_permissions: 3 | command: "sudo chmod -R 777 /var/app/ondeck/tmp" 4 | -------------------------------------------------------------------------------- /chapter10/tandibi/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /chapter10/tandibi/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.6.5 2 | -------------------------------------------------------------------------------- /chapter10/tandibi/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/app/assets/images/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/app/assets/stylesheets/home.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: https://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/controllers/api/v1/places_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::PlacesController < ApplicationController 2 | def index 3 | keyword = params.fetch(:keyword) 4 | lat = params.fetch(:lat) 5 | lng = params.fetch(:lng) 6 | 7 | PlaceCrawlerJob.perform_later(keyword, lat: lat, lng: lng) 8 | render json: Place::Finder.call(keyword, lat: lat, lng: lng) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | redirect_to(timelines_path) if user_signed_in? 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/decorators/sight_decorator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SightDecorator 4 | def humanized_activity_type 5 | case activity_type 6 | when Sight::CHECKIN then "checked in at" 7 | when Sight::CHECKOUT then "checked out from" 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/helpers/posts_helper.rb: -------------------------------------------------------------------------------- 1 | module PostsHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/helpers/settings/users_helper.rb: -------------------------------------------------------------------------------- 1 | module Settings::UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/javascript/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | 23 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/javascript/css/application.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | @import "common"; 6 | @import "modal"; 7 | @import "home"; 8 | @import "session"; 9 | @import "member"; 10 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/javascript/css/common.css: -------------------------------------------------------------------------------- 1 | .alert { 2 | @apply text-white text-sm text-center font-medium px-4 py-3; 3 | } 4 | 5 | a { 6 | @apply no-underline text-blue-400; 7 | } 8 | 9 | a:hover { 10 | @apply text-blue-500; 11 | } 12 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/javascript/lib/filters.js: -------------------------------------------------------------------------------- 1 | export function truncate(text, length) { 2 | const clamp = "..." 3 | if (text.length <= length) { 4 | return text 5 | } else { 6 | let subString = text.substr(0, length-1) 7 | let lastSpaceIdx = subString.lastIndexOf(' ') 8 | subString = subString.substr(0, lastSpaceIdx) 9 | return subString + clamp 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/jobs/place_crawler_job.rb: -------------------------------------------------------------------------------- 1 | class PlaceCrawlerJob < ApplicationJob 2 | queue_as :default 3 | 4 | def perform(name, lat:, lng:) 5 | Place::Crawler.call(name, lat: lat, lng: lng) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/app/models/concerns/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/app/models/status.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | class Status < ApplicationRecord 11 | validates :text, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/serializers/place_serializer.rb: -------------------------------------------------------------------------------- 1 | class PlaceSerializer < ActiveModel::Serializer 2 | attributes :id, 3 | :locale, 4 | :name, 5 | :place_type, 6 | :coordinates 7 | 8 | def coordinates 9 | coordinate = object.coordinate 10 | { 11 | lng: coordinate.longitude, 12 | lat: coordinate.latitude, 13 | } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/services/application_service.rb: -------------------------------------------------------------------------------- 1 | class ApplicationService 2 | def self.call(*args) 3 | new(*args).call 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/services/bond/rejector.rb: -------------------------------------------------------------------------------- 1 | class Bond::Rejector < ApplicationService 2 | attr_reader :requester, :target_user 3 | private :requester, :target_user 4 | 5 | def initialize(requester, target_user) 6 | @requester = requester 7 | @target_user = target_user 8 | end 9 | 10 | def call 11 | requester.bonds.where(friend: target_user).destroy_all 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/bonds/following.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "timelines/profile_header", user: visited_user %> 2 | 3 | <%= render "bonds/users_list", 4 | users: @bonded_users do |each_user| %> 5 | 6 | <%= render "bonds/bonding_buttons", user: each_user %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/devise/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Password changed

2 | 3 |

Hello <%= @resource.email %>!

4 | 5 |

We're contacting you to notify you that your password has been changed.

6 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/home/_action_button.html.erb: -------------------------------------------------------------------------------- 1 | <% method = local_assigns.fetch(:method, :get) %> 2 | 3 | <%= link_to link, class: "action", method: method do %> 4 | <%= caption %> 5 | <%= evil_icon icon, size: :s, class: "arrow" %> 6 | <% end %> 7 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/layouts/_alert.html.erb: -------------------------------------------------------------------------------- 1 | <% if notice && notice.present? %> 2 | 5 | <% end %> 6 | 7 | <% if alert && alert.present? %> 8 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= render "layouts/header" %> 4 | 5 | 6 | <%= render "layouts/alert" %> 7 | 8 | <%= yield %> 9 | 10 | 11 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/posts/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= render "timelines/line", 4 | post: @post, 5 | show_replies: true %> 6 |
7 |
8 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/settings/users/update.html.erb: -------------------------------------------------------------------------------- 1 |

Settings::Users#update

2 |

Find me in app/views/settings/users/update.html.erb

3 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/timelines/_all.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% @posts.each do |post| %> 3 |
4 | <%= render "timelines/line", post: post %> 5 |
6 | <% end %> 7 |
8 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/timelines/_profile_stat.html.erb: -------------------------------------------------------------------------------- 1 | <% is_active = local_assigns.fetch(:is_active, false) %> 2 | 3 | <%= link_to link_to, class: "stat #{"active" if is_active}" do %> 4 |

<%= count %>

5 |

<%= counter %>

6 | <% end %> 7 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/timelines/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= render("posts/form") %> 2 | 3 | <%= render "timelines/all" %> 4 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/timelines/show.en-US.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "timelines/profile_header", user: @visited_user %> 2 | 3 | <% if on_self? %> 4 | <%= render("posts/form") %> 5 | <% end %> 6 | 7 | <% if can? current_user, :see_timeline, @visited_user %> 8 | <%= render "timelines/all" %> 9 | <% else %> 10 |

These posts are protected

11 | <% end %> 12 | -------------------------------------------------------------------------------- /chapter10/tandibi/app/views/timelines/show.id.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "timelines/profile_header", user: @visited_user %> 2 | 3 | <% if on_self? %> 4 | <%= render("posts/form") %> 5 | <% end %> 6 | 7 | <% if can? current_user, :see_timeline, @visited_user %> 8 | <%= render "timelines/all" %> 9 | <% else %> 10 |

11 | Post ditampilkan hanya untuk pengikut 12 |

13 | <% end %> 14 | -------------------------------------------------------------------------------- /chapter10/tandibi/bin/delayed_job: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) 4 | require 'delayed/command' 5 | Delayed::Command.new(ARGV).daemonize 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /chapter10/tandibi/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /chapter10/tandibi/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /chapter10/tandibi/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: tandibi_production 11 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/locales/en-US.yml: -------------------------------------------------------------------------------- 1 | en-US: 2 | common: 3 | say: Say 4 | 5 | posts: 6 | form: 7 | whats_happening: What's happening? 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/locales/id.yml: -------------------------------------------------------------------------------- 1 | id: 2 | common: 3 | say: Kata 4 | 5 | posts: 6 | form: 7 | whats_happening: Apa yang terjadi? 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | const { VueLoaderPlugin } = require('vue-loader') 3 | const vue = require('./loaders/vue') 4 | 5 | environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin()) 6 | environment.loaders.prepend('vue', vue) 7 | module.exports = environment 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/webpack/loaders/vue.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test: /\.vue(\.erb)?$/, 3 | use: [{ 4 | loader: 'vue-loader' 5 | }] 6 | } 7 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/db/migrate/20200224224200_create_pictures.rb: -------------------------------------------------------------------------------- 1 | class CreatePictures < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :pictures do |t| 4 | t.string :caption 5 | t.bigint :post_id, null: false 6 | 7 | t.timestamps 8 | end 9 | 10 | add_foreign_key :pictures, :posts 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /chapter10/tandibi/db/migrate/20200224230539_create_statuses.rb: -------------------------------------------------------------------------------- 1 | class CreateStatuses < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :statuses do |t| 4 | t.string :text, null: false 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /chapter10/tandibi/db/migrate/20200225083408_create_sights.rb: -------------------------------------------------------------------------------- 1 | class CreateSights < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :sights do |t| 4 | t.references :place, null: false, foreign_key: true 5 | t.string :activity_type, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter10/tandibi/db/migrate/20200510232213_add_locale_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddLocaleToUsers < ActiveRecord::Migration[6.0] 2 | def change 3 | add_column :users, :locale, :string, 4 | null: false, 5 | default: "en-US" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | eval "bundle install -j8" 5 | eval "yarn install --check-files" 6 | 7 | exec "$@" 8 | -------------------------------------------------------------------------------- /chapter10/tandibi/lgtm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/lgtm.png -------------------------------------------------------------------------------- /chapter10/tandibi/lgtm2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/lgtm2.gif -------------------------------------------------------------------------------- /chapter10/tandibi/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/lib/assets/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/lib/tasks/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/log/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('tailwindcss')('./app/javascript/css/tailwind.js'), 6 | require('autoprefixer'), 7 | require('postcss-preset-env')({ 8 | autoprefixer: { 9 | flexbox: 'no-2009' 10 | }, 11 | stage: 3 12 | }) 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /chapter10/tandibi/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /chapter10/tandibi/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/public/apple-touch-icon.png -------------------------------------------------------------------------------- /chapter10/tandibi/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/public/favicon.ico -------------------------------------------------------------------------------- /chapter10/tandibi/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /chapter10/tandibi/spec/factories/statuses.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | FactoryBot.define do 11 | factory :status do 12 | text { "MyString" } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter10/tandibi/spec/support/api.rb: -------------------------------------------------------------------------------- 1 | def json_response 2 | JSON.parse response.body 3 | end 4 | -------------------------------------------------------------------------------- /chapter10/tandibi/spec/support/devise.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include Devise::Test::IntegrationHelpers, 3 | type: :request 4 | end 5 | -------------------------------------------------------------------------------- /chapter10/tandibi/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /chapter10/tandibi/spec/support/job.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include ActiveJob::TestHelper, type: :job 3 | config.include ActiveJob::TestHelper, type: :request 4 | end 5 | -------------------------------------------------------------------------------- /chapter10/tandibi/spec/support/vcr.rb: -------------------------------------------------------------------------------- 1 | require "vcr" 2 | 3 | VCR.configure do |config| 4 | config.cassette_library_dir = "spec/fixtures/vcr_cassettes" 5 | config.hook_into :faraday 6 | end 7 | -------------------------------------------------------------------------------- /chapter10/tandibi/spec/views/home/index.html.erb_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe "home/index.html.erb", type: :view do 4 | pending "add some examples to (or delete) #{__FILE__}" 5 | end 6 | -------------------------------------------------------------------------------- /chapter10/tandibi/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/storage/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/tmp/.keep -------------------------------------------------------------------------------- /chapter10/tandibi/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter10/tandibi/vendor/.keep -------------------------------------------------------------------------------- /chapter3/coolprint/.tool-versions: -------------------------------------------------------------------------------- 1 | ruby 2.6.5 2 | -------------------------------------------------------------------------------- /chapter3/coolprint/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | ruby "2.6.5" 3 | 4 | gem "colorize", "0.8.1" 5 | -------------------------------------------------------------------------------- /chapter3/coolprint/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | colorize (0.8.1) 5 | 6 | PLATFORMS 7 | ruby 8 | 9 | DEPENDENCIES 10 | colorize (= 0.8.1) 11 | 12 | RUBY VERSION 13 | ruby 2.6.5p114 14 | 15 | BUNDLED WITH 16 | 2.1.4 17 | -------------------------------------------------------------------------------- /chapter3/coolprint/app.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler/setup' 3 | require "colorize" 4 | 5 | puts "Hello ".colorize(:red) 6 | puts "World".colorize(:blue) 7 | -------------------------------------------------------------------------------- /chapter4/tandibi/.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /chapter4/tandibi/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /chapter4/tandibi/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.6.5 2 | -------------------------------------------------------------------------------- /chapter4/tandibi/README.md: -------------------------------------------------------------------------------- 1 | # Tandibi 2 | 3 | [Tandibi](https://tandibi.com) is a social media app we are building in the book "Learning Rails 6" 4 | -------------------------------------------------------------------------------- /chapter4/tandibi/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/app/assets/images/.keep -------------------------------------------------------------------------------- /chapter4/tandibi/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | end 3 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /chapter4/tandibi/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/app/models/concerns/.keep -------------------------------------------------------------------------------- /chapter4/tandibi/app/models/status.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | class Status < ApplicationRecord 11 | validates :text, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /chapter4/tandibi/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /chapter4/tandibi/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /chapter4/tandibi/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /chapter4/tandibi/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /chapter4/tandibi/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: tandibi_production 11 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 3 | end 4 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | module.exports = environment 4 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter4/tandibi/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter4/tandibi/db/migrate/20200224224200_create_pictures.rb: -------------------------------------------------------------------------------- 1 | class CreatePictures < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :pictures do |t| 4 | t.string :caption 5 | t.bigint :post_id, null: false 6 | 7 | t.timestamps 8 | end 9 | 10 | add_foreign_key :pictures, :posts 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /chapter4/tandibi/db/migrate/20200224230539_create_statuses.rb: -------------------------------------------------------------------------------- 1 | class CreateStatuses < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :statuses do |t| 4 | t.string :text, null: false 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /chapter4/tandibi/db/migrate/20200225083408_create_sights.rb: -------------------------------------------------------------------------------- 1 | class CreateSights < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :sights do |t| 4 | t.references :place, null: false, foreign_key: true 5 | t.string :activity_type, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter4/tandibi/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/lib/assets/.keep -------------------------------------------------------------------------------- /chapter4/tandibi/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/lib/tasks/.keep -------------------------------------------------------------------------------- /chapter4/tandibi/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/log/.keep -------------------------------------------------------------------------------- /chapter4/tandibi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tandibi", 3 | "private": true, 4 | "dependencies": { 5 | "@rails/actioncable": "^6.0.0", 6 | "@rails/activestorage": "^6.0.0", 7 | "@rails/ujs": "^6.0.0", 8 | "@rails/webpacker": "4.2.2", 9 | "turbolinks": "^5.2.0" 10 | }, 11 | "version": "0.1.0", 12 | "devDependencies": { 13 | "webpack-dev-server": "^3.10.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /chapter4/tandibi/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('postcss-preset-env')({ 6 | autoprefixer: { 7 | flexbox: 'no-2009' 8 | }, 9 | stage: 3 10 | }) 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /chapter4/tandibi/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /chapter4/tandibi/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/public/apple-touch-icon.png -------------------------------------------------------------------------------- /chapter4/tandibi/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/public/favicon.ico -------------------------------------------------------------------------------- /chapter4/tandibi/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /chapter4/tandibi/spec/factories/statuses.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | FactoryBot.define do 11 | factory :status do 12 | text { "MyString" } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter4/tandibi/spec/models/status_spec.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | require 'rails_helper' 11 | 12 | RSpec.describe Status, type: :model do 13 | pending "add some examples to (or delete) #{__FILE__}" 14 | end 15 | -------------------------------------------------------------------------------- /chapter4/tandibi/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /chapter4/tandibi/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/storage/.keep -------------------------------------------------------------------------------- /chapter4/tandibi/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/tmp/.keep -------------------------------------------------------------------------------- /chapter4/tandibi/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter4/tandibi/vendor/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /chapter5/tandibi/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /chapter5/tandibi/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.6.5 2 | -------------------------------------------------------------------------------- /chapter5/tandibi/README.md: -------------------------------------------------------------------------------- 1 | # Tandibi 2 | 3 | [Tandibi](https://tandibi.com) is a social media app we are building in the book "Learning Rails 6" 4 | -------------------------------------------------------------------------------- /chapter5/tandibi/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/app/assets/images/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/app/assets/stylesheets/home.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: https://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/javascript/css/application.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | @import "common"; 6 | @import "home"; 7 | @import "session"; 8 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/javascript/css/common.css: -------------------------------------------------------------------------------- 1 | .alert { 2 | @apply text-white text-sm text-center font-medium px-4 py-3; 3 | } 4 | 5 | a { 6 | @apply no-underline text-blue-400; 7 | } 8 | 9 | a:hover { 10 | @apply text-blue-500; 11 | } 12 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/javascript/css/tailwind.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | theme: { 3 | extend: { 4 | colors: { 5 | main: { 6 | default: "#60b0e2", 7 | "500": "#41a1dd", 8 | } 9 | }, 10 | spacing: { 11 | '72': '18rem', 12 | '84': '21rem', 13 | '96': '24rem', 14 | } 15 | }, 16 | }, 17 | variants: {}, 18 | plugins: [], 19 | } 20 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/app/models/concerns/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/app/models/status.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | class Status < ApplicationRecord 11 | validates :text, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/views/devise/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Password changed

2 | 3 |

Hello <%= @resource.email %>!

4 | 5 |

We're contacting you to notify you that your password has been changed.

6 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/views/home/_action_button.html.erb: -------------------------------------------------------------------------------- 1 | <% method = local_assigns.fetch(:method, :get) %> 2 | 3 | <%= link_to link, class: "action", method: method do %> 4 | <%= caption %> 5 | <%= evil_icon icon, size: :s, class: "arrow" %> 6 | <% end %> 7 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/views/layouts/_alert.html.erb: -------------------------------------------------------------------------------- 1 | <% if notice && notice.present? %> 2 | 5 | <% end %> 6 | 7 | <% if alert && alert.present? %> 8 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /chapter5/tandibi/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /chapter5/tandibi/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /chapter5/tandibi/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /chapter5/tandibi/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /chapter5/tandibi/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: tandibi_production 11 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | devise_for :users 3 | root to: 'home#index' 4 | # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 5 | 6 | if Rails.env.development? 7 | mount LetterOpenerWeb::Engine, at: "/letter_opener" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | module.exports = environment 4 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter5/tandibi/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter5/tandibi/db/migrate/20200224224200_create_pictures.rb: -------------------------------------------------------------------------------- 1 | class CreatePictures < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :pictures do |t| 4 | t.string :caption 5 | t.bigint :post_id, null: false 6 | 7 | t.timestamps 8 | end 9 | 10 | add_foreign_key :pictures, :posts 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /chapter5/tandibi/db/migrate/20200224230539_create_statuses.rb: -------------------------------------------------------------------------------- 1 | class CreateStatuses < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :statuses do |t| 4 | t.string :text, null: false 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /chapter5/tandibi/db/migrate/20200225083408_create_sights.rb: -------------------------------------------------------------------------------- 1 | class CreateSights < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :sights do |t| 4 | t.references :place, null: false, foreign_key: true 5 | t.string :activity_type, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter5/tandibi/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/lib/assets/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/lib/tasks/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/log/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tandibi", 3 | "private": true, 4 | "dependencies": { 5 | "@rails/actioncable": "^6.0.0", 6 | "@rails/activestorage": "^6.0.0", 7 | "@rails/ujs": "^6.0.0", 8 | "@rails/webpacker": "4.2.2", 9 | "turbolinks": "^5.2.0" 10 | }, 11 | "version": "0.1.0", 12 | "devDependencies": { 13 | "tailwindcss": "^1.2.0", 14 | "webpack-dev-server": "^3.10.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter5/tandibi/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('tailwindcss')('./app/javascript/css/tailwind.js'), 6 | require('autoprefixer'), 7 | require('postcss-preset-env')({ 8 | autoprefixer: { 9 | flexbox: 'no-2009' 10 | }, 11 | stage: 3 12 | }) 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /chapter5/tandibi/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /chapter5/tandibi/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/public/apple-touch-icon.png -------------------------------------------------------------------------------- /chapter5/tandibi/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/public/favicon.ico -------------------------------------------------------------------------------- /chapter5/tandibi/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /chapter5/tandibi/spec/factories/statuses.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | FactoryBot.define do 11 | factory :status do 12 | text { "MyString" } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter5/tandibi/spec/models/status_spec.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | require 'rails_helper' 11 | 12 | RSpec.describe Status, type: :model do 13 | pending "add some examples to (or delete) #{__FILE__}" 14 | end 15 | -------------------------------------------------------------------------------- /chapter5/tandibi/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /chapter5/tandibi/spec/views/home/index.html.erb_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe "home/index.html.erb", type: :view do 4 | pending "add some examples to (or delete) #{__FILE__}" 5 | end 6 | -------------------------------------------------------------------------------- /chapter5/tandibi/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/storage/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/tmp/.keep -------------------------------------------------------------------------------- /chapter5/tandibi/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter5/tandibi/vendor/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /chapter6/tandibi/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /chapter6/tandibi/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.6.5 2 | -------------------------------------------------------------------------------- /chapter6/tandibi/README.md: -------------------------------------------------------------------------------- 1 | # Tandibi 2 | 3 | [Tandibi](https://tandibi.com) is a social media app we are building in the book "Learning Rails 6" 4 | -------------------------------------------------------------------------------- /chapter6/tandibi/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/app/assets/images/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/app/assets/stylesheets/home.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: https://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | redirect_to(timelines_path) if user_signed_in? 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/decorators/sight_decorator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SightDecorator 4 | def humanized_activity_type 5 | case activity_type 6 | when Sight::CHECKIN then "checked in at" 7 | when Sight::CHECKOUT then "checked out from" 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/helpers/posts_helper.rb: -------------------------------------------------------------------------------- 1 | module PostsHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/helpers/timelines_helper.rb: -------------------------------------------------------------------------------- 1 | module TimelinesHelper 2 | def on_timeline? 3 | controller_path == "timelines" 4 | end 5 | 6 | def on_bunch? 7 | on_timeline? && action_name == "index" 8 | end 9 | 10 | def on_self? 11 | on_timeline? && action_name == "show" && 12 | params[:username] == current_user.username 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/javascript/css/application.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | @import "common"; 6 | @import "modal"; 7 | @import "home"; 8 | @import "session"; 9 | @import "member"; 10 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/javascript/css/common.css: -------------------------------------------------------------------------------- 1 | .alert { 2 | @apply text-white text-sm text-center font-medium px-4 py-3; 3 | } 4 | 5 | a { 6 | @apply no-underline text-blue-400; 7 | } 8 | 9 | a:hover { 10 | @apply text-blue-500; 11 | } 12 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/javascript/css/member.css: -------------------------------------------------------------------------------- 1 | @import "member/nav"; 2 | @import "member/timeline"; 3 | @import "member/poster"; 4 | 5 | .body-member { 6 | @apply bg-gray-100 font-sans; 7 | } 8 | 9 | .body-member 10 | .container { 11 | @apply mx-auto; 12 | } 13 | 14 | .body-member.dark { 15 | @apply bg-dark-800; 16 | @apply text-gray-100; 17 | } 18 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/app/models/concerns/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/app/models/status.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | class Status < ApplicationRecord 11 | validates :text, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/services/application_service.rb: -------------------------------------------------------------------------------- 1 | class ApplicationService 2 | def self.call(*args) 3 | new(*args).call 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/devise/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Password changed

2 | 3 |

Hello <%= @resource.email %>!

4 | 5 |

We're contacting you to notify you that your password has been changed.

6 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/home/_action_button.html.erb: -------------------------------------------------------------------------------- 1 | <% method = local_assigns.fetch(:method, :get) %> 2 | 3 | <%= link_to link, class: "action", method: method do %> 4 | <%= caption %> 5 | <%= evil_icon icon, size: :s, class: "arrow" %> 6 | <% end %> 7 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/layouts/_alert.html.erb: -------------------------------------------------------------------------------- 1 | <% if notice && notice.present? %> 2 | 5 | <% end %> 6 | 7 | <% if alert && alert.present? %> 8 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= render "layouts/header" %> 4 | 5 | 6 | <%= render "layouts/alert" %> 7 | 8 | <%= yield %> 9 | 10 | 11 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/posts/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= render "timelines/line", 4 | post: @post, 5 | show_replies: true %> 6 |
7 |
8 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/timelines/_all.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% @posts.each do |post| %> 3 |
4 | <%= render "timelines/line", post: post %> 5 |
6 | <% end %> 7 |
8 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/timelines/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= render("posts/form") %> 2 | 3 | <%= render "timelines/all" %> 4 | -------------------------------------------------------------------------------- /chapter6/tandibi/app/views/timelines/show.html.erb: -------------------------------------------------------------------------------- 1 | <% if on_self? %> 2 | <%= render("posts/form") %> 3 | <% end %> 4 | 5 | <%= render "timelines/all" %> 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /chapter6/tandibi/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /chapter6/tandibi/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /chapter6/tandibi/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: tandibi_production 11 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | module.exports = environment 4 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/db/migrate/20200224224200_create_pictures.rb: -------------------------------------------------------------------------------- 1 | class CreatePictures < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :pictures do |t| 4 | t.string :caption 5 | t.bigint :post_id, null: false 6 | 7 | t.timestamps 8 | end 9 | 10 | add_foreign_key :pictures, :posts 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /chapter6/tandibi/db/migrate/20200224230539_create_statuses.rb: -------------------------------------------------------------------------------- 1 | class CreateStatuses < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :statuses do |t| 4 | t.string :text, null: false 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /chapter6/tandibi/db/migrate/20200225083408_create_sights.rb: -------------------------------------------------------------------------------- 1 | class CreateSights < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :sights do |t| 4 | t.references :place, null: false, foreign_key: true 5 | t.string :activity_type, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter6/tandibi/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/lib/assets/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/lib/tasks/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/log/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tandibi", 3 | "private": true, 4 | "dependencies": { 5 | "@rails/actioncable": "^6.0.0", 6 | "@rails/activestorage": "^6.0.0", 7 | "@rails/ujs": "^6.0.0", 8 | "@rails/webpacker": "4.2.2", 9 | "turbolinks": "^5.2.0" 10 | }, 11 | "version": "0.1.0", 12 | "devDependencies": { 13 | "tailwindcss": "^1.2.0", 14 | "webpack-dev-server": "^3.10.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter6/tandibi/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('tailwindcss')('./app/javascript/css/tailwind.js'), 6 | require('autoprefixer'), 7 | require('postcss-preset-env')({ 8 | autoprefixer: { 9 | flexbox: 'no-2009' 10 | }, 11 | stage: 3 12 | }) 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /chapter6/tandibi/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /chapter6/tandibi/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/public/apple-touch-icon.png -------------------------------------------------------------------------------- /chapter6/tandibi/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/public/favicon.ico -------------------------------------------------------------------------------- /chapter6/tandibi/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /chapter6/tandibi/spec/factories/statuses.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | FactoryBot.define do 11 | factory :status do 12 | text { "MyString" } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter6/tandibi/spec/models/status_spec.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | require 'rails_helper' 11 | 12 | RSpec.describe Status, type: :model do 13 | pending "add some examples to (or delete) #{__FILE__}" 14 | end 15 | -------------------------------------------------------------------------------- /chapter6/tandibi/spec/support/devise.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include Devise::Test::IntegrationHelpers, 3 | type: :request 4 | end 5 | -------------------------------------------------------------------------------- /chapter6/tandibi/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /chapter6/tandibi/spec/views/home/index.html.erb_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe "home/index.html.erb", type: :view do 4 | pending "add some examples to (or delete) #{__FILE__}" 5 | end 6 | -------------------------------------------------------------------------------- /chapter6/tandibi/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/storage/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/tmp/.keep -------------------------------------------------------------------------------- /chapter6/tandibi/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter6/tandibi/vendor/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /chapter7/tandibi/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /chapter7/tandibi/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.6.5 2 | -------------------------------------------------------------------------------- /chapter7/tandibi/README.md: -------------------------------------------------------------------------------- 1 | # Tandibi 2 | 3 | [Tandibi](https://tandibi.com) is a social media app we are building in the book "Learning Rails 6" 4 | 5 | Note: 6 | 7 | If you clone this repository. Please be aware that you will need to key in the API key for the Amazon S3 credentials. Otherwise, the app might not function as intended. 8 | -------------------------------------------------------------------------------- /chapter7/tandibi/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/app/assets/images/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/app/assets/stylesheets/home.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: https://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | redirect_to(timelines_path) if user_signed_in? 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/decorators/sight_decorator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SightDecorator 4 | def humanized_activity_type 5 | case activity_type 6 | when Sight::CHECKIN then "checked in at" 7 | when Sight::CHECKOUT then "checked out from" 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/helpers/posts_helper.rb: -------------------------------------------------------------------------------- 1 | module PostsHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/helpers/timelines_helper.rb: -------------------------------------------------------------------------------- 1 | module TimelinesHelper 2 | def on_timeline? 3 | controller_path == "timelines" 4 | end 5 | 6 | def on_bunch? 7 | on_timeline? && action_name == "index" 8 | end 9 | 10 | def on_self? 11 | on_timeline? && action_name == "show" && 12 | params[:username] == current_user.username 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/javascript/css/application.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | @import "common"; 6 | @import "modal"; 7 | @import "home"; 8 | @import "session"; 9 | @import "member"; 10 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/javascript/css/common.css: -------------------------------------------------------------------------------- 1 | .alert { 2 | @apply text-white text-sm text-center font-medium px-4 py-3; 3 | } 4 | 5 | a { 6 | @apply no-underline text-blue-400; 7 | } 8 | 9 | a:hover { 10 | @apply text-blue-500; 11 | } 12 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/javascript/css/member.css: -------------------------------------------------------------------------------- 1 | @import "member/nav"; 2 | @import "member/timeline"; 3 | @import "member/poster"; 4 | 5 | .body-member { 6 | @apply bg-gray-100 font-sans; 7 | } 8 | 9 | .body-member 10 | .container { 11 | @apply mx-auto; 12 | } 13 | 14 | .body-member.dark { 15 | @apply bg-dark-800; 16 | @apply text-gray-100; 17 | } 18 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/app/models/concerns/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/app/models/status.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | class Status < ApplicationRecord 11 | validates :text, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/services/application_service.rb: -------------------------------------------------------------------------------- 1 | class ApplicationService 2 | def self.call(*args) 3 | new(*args).call 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/devise/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Password changed

2 | 3 |

Hello <%= @resource.email %>!

4 | 5 |

We're contacting you to notify you that your password has been changed.

6 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/home/_action_button.html.erb: -------------------------------------------------------------------------------- 1 | <% method = local_assigns.fetch(:method, :get) %> 2 | 3 | <%= link_to link, class: "action", method: method do %> 4 | <%= caption %> 5 | <%= evil_icon icon, size: :s, class: "arrow" %> 6 | <% end %> 7 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/layouts/_alert.html.erb: -------------------------------------------------------------------------------- 1 | <% if notice && notice.present? %> 2 | 5 | <% end %> 6 | 7 | <% if alert && alert.present? %> 8 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= render "layouts/header" %> 4 | 5 | 6 | <%= render "layouts/alert" %> 7 | 8 | <%= yield %> 9 | 10 | 11 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/posts/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= render "timelines/line", 4 | post: @post, 5 | show_replies: true %> 6 |
7 |
8 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/timelines/_all.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% @posts.each do |post| %> 3 |
4 | <%= render "timelines/line", post: post %> 5 |
6 | <% end %> 7 |
8 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/timelines/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= render("posts/form") %> 2 | 3 | <%= render "timelines/all" %> 4 | -------------------------------------------------------------------------------- /chapter7/tandibi/app/views/timelines/show.html.erb: -------------------------------------------------------------------------------- 1 | <% if on_self? %> 2 | <%= render("posts/form") %> 3 | <% end %> 4 | 5 | <%= render "timelines/all" %> 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /chapter7/tandibi/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /chapter7/tandibi/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /chapter7/tandibi/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: tandibi_production 11 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | module.exports = environment 4 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/db/migrate/20200224224200_create_pictures.rb: -------------------------------------------------------------------------------- 1 | class CreatePictures < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :pictures do |t| 4 | t.string :caption 5 | t.bigint :post_id, null: false 6 | 7 | t.timestamps 8 | end 9 | 10 | add_foreign_key :pictures, :posts 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /chapter7/tandibi/db/migrate/20200224230539_create_statuses.rb: -------------------------------------------------------------------------------- 1 | class CreateStatuses < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :statuses do |t| 4 | t.string :text, null: false 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /chapter7/tandibi/db/migrate/20200225083408_create_sights.rb: -------------------------------------------------------------------------------- 1 | class CreateSights < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :sights do |t| 4 | t.references :place, null: false, foreign_key: true 5 | t.string :activity_type, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter7/tandibi/lgtm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/lgtm.png -------------------------------------------------------------------------------- /chapter7/tandibi/lgtm2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/lgtm2.gif -------------------------------------------------------------------------------- /chapter7/tandibi/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/lib/assets/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/lib/tasks/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/log/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tandibi", 3 | "private": true, 4 | "dependencies": { 5 | "@rails/actioncable": "^6.0.0", 6 | "@rails/activestorage": "^6.0.0", 7 | "@rails/ujs": "^6.0.0", 8 | "@rails/webpacker": "4.2.2", 9 | "turbolinks": "^5.2.0" 10 | }, 11 | "version": "0.1.0", 12 | "devDependencies": { 13 | "tailwindcss": "^1.2.0", 14 | "webpack-dev-server": "^3.10.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter7/tandibi/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('tailwindcss')('./app/javascript/css/tailwind.js'), 6 | require('autoprefixer'), 7 | require('postcss-preset-env')({ 8 | autoprefixer: { 9 | flexbox: 'no-2009' 10 | }, 11 | stage: 3 12 | }) 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /chapter7/tandibi/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /chapter7/tandibi/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/public/apple-touch-icon.png -------------------------------------------------------------------------------- /chapter7/tandibi/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/public/favicon.ico -------------------------------------------------------------------------------- /chapter7/tandibi/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /chapter7/tandibi/spec/factories/statuses.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | FactoryBot.define do 11 | factory :status do 12 | text { "MyString" } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter7/tandibi/spec/models/status_spec.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | require 'rails_helper' 11 | 12 | RSpec.describe Status, type: :model do 13 | pending "add some examples to (or delete) #{__FILE__}" 14 | end 15 | -------------------------------------------------------------------------------- /chapter7/tandibi/spec/support/capybara.rb: -------------------------------------------------------------------------------- 1 | require "capybara/rspec" 2 | require "capybara/apparition" 3 | 4 | Capybara.default_driver = :apparition 5 | Capybara.javascript_driver = :apparition 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/spec/support/devise.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include Devise::Test::IntegrationHelpers, 3 | type: :request 4 | end 5 | -------------------------------------------------------------------------------- /chapter7/tandibi/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /chapter7/tandibi/spec/views/home/index.html.erb_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe "home/index.html.erb", type: :view do 4 | pending "add some examples to (or delete) #{__FILE__}" 5 | end 6 | -------------------------------------------------------------------------------- /chapter7/tandibi/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/storage/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/tmp/.keep -------------------------------------------------------------------------------- /chapter7/tandibi/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter7/tandibi/vendor/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /chapter8/tandibi/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /chapter8/tandibi/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.6.5 2 | -------------------------------------------------------------------------------- /chapter8/tandibi/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/app/assets/images/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/app/assets/stylesheets/home.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: https://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/controllers/api/v1/places_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::PlacesController < ApplicationController 2 | def index 3 | keyword = params.fetch(:keyword) 4 | lat = params.fetch(:lat) 5 | lng = params.fetch(:lng) 6 | 7 | PlaceCrawlerJob.perform_later(keyword, lat: lat, lng: lng) 8 | render json: Place::Finder.call(keyword, lat: lat, lng: lng) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | redirect_to(timelines_path) if user_signed_in? 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/decorators/sight_decorator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SightDecorator 4 | def humanized_activity_type 5 | case activity_type 6 | when Sight::CHECKIN then "checked in at" 7 | when Sight::CHECKOUT then "checked out from" 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def google_map_api_url 3 | credentials = Rails.application.credentials 4 | key = credentials.dig(:google, :credentials, :map) 5 | 6 | "https://maps.googleapis.com/maps/api/js?key=" + key 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/helpers/posts_helper.rb: -------------------------------------------------------------------------------- 1 | module PostsHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/helpers/timelines_helper.rb: -------------------------------------------------------------------------------- 1 | module TimelinesHelper 2 | def on_timeline? 3 | controller_path == "timelines" 4 | end 5 | 6 | def on_bunch? 7 | on_timeline? && action_name == "index" 8 | end 9 | 10 | def on_self? 11 | on_timeline? && action_name == "show" && 12 | params[:username] == current_user.username 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/javascript/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | 23 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/javascript/css/application.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | @import "common"; 6 | @import "modal"; 7 | @import "home"; 8 | @import "session"; 9 | @import "member"; 10 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/javascript/css/common.css: -------------------------------------------------------------------------------- 1 | .alert { 2 | @apply text-white text-sm text-center font-medium px-4 py-3; 3 | } 4 | 5 | a { 6 | @apply no-underline text-blue-400; 7 | } 8 | 9 | a:hover { 10 | @apply text-blue-500; 11 | } 12 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/javascript/css/member.css: -------------------------------------------------------------------------------- 1 | @import "member/nav"; 2 | @import "member/timeline"; 3 | @import "member/poster"; 4 | 5 | .body-member { 6 | @apply bg-gray-100 font-sans; 7 | } 8 | 9 | .body-member 10 | .container { 11 | @apply mx-auto; 12 | } 13 | 14 | .body-member.dark { 15 | @apply bg-dark-800; 16 | @apply text-gray-100; 17 | } 18 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/javascript/lib/filters.js: -------------------------------------------------------------------------------- 1 | export function truncate(text, length) { 2 | const clamp = "..." 3 | if (text.length <= length) { 4 | return text 5 | } else { 6 | let subString = text.substr(0, length-1) 7 | let lastSpaceIdx = subString.lastIndexOf(' ') 8 | subString = subString.substr(0, lastSpaceIdx) 9 | return subString + clamp 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/jobs/place_crawler_job.rb: -------------------------------------------------------------------------------- 1 | class PlaceCrawlerJob < ApplicationJob 2 | queue_as :default 3 | 4 | def perform(name, lat:, lng:) 5 | Place::Crawler.call(name, lat: lat, lng: lng) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/app/models/concerns/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/app/models/status.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | class Status < ApplicationRecord 11 | validates :text, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/serializers/place_serializer.rb: -------------------------------------------------------------------------------- 1 | class PlaceSerializer < ActiveModel::Serializer 2 | attributes :id, 3 | :locale, 4 | :name, 5 | :place_type, 6 | :coordinates 7 | 8 | def coordinates 9 | coordinate = object.coordinate 10 | { 11 | lng: coordinate.longitude, 12 | lat: coordinate.latitude, 13 | } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/services/application_service.rb: -------------------------------------------------------------------------------- 1 | class ApplicationService 2 | def self.call(*args) 3 | new(*args).call 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/devise/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Password changed

2 | 3 |

Hello <%= @resource.email %>!

4 | 5 |

We're contacting you to notify you that your password has been changed.

6 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/home/_action_button.html.erb: -------------------------------------------------------------------------------- 1 | <% method = local_assigns.fetch(:method, :get) %> 2 | 3 | <%= link_to link, class: "action", method: method do %> 4 | <%= caption %> 5 | <%= evil_icon icon, size: :s, class: "arrow" %> 6 | <% end %> 7 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/layouts/_alert.html.erb: -------------------------------------------------------------------------------- 1 | <% if notice && notice.present? %> 2 | 5 | <% end %> 6 | 7 | <% if alert && alert.present? %> 8 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= render "layouts/header" %> 4 | 5 | 6 | <%= render "layouts/alert" %> 7 | 8 | <%= yield %> 9 | 10 | 11 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/posts/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= render "timelines/line", 4 | post: @post, 5 | show_replies: true %> 6 |
7 |
8 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/timelines/_all.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% @posts.each do |post| %> 3 |
4 | <%= render "timelines/line", post: post %> 5 |
6 | <% end %> 7 |
8 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/timelines/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= render("posts/form") %> 2 | 3 | <%= render "timelines/all" %> 4 | -------------------------------------------------------------------------------- /chapter8/tandibi/app/views/timelines/show.html.erb: -------------------------------------------------------------------------------- 1 | <% if on_self? %> 2 | <%= render("posts/form") %> 3 | <% end %> 4 | 5 | <%= render "timelines/all" %> 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/bin/delayed_job: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) 4 | require 'delayed/command' 5 | Delayed::Command.new(ARGV).daemonize 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /chapter8/tandibi/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /chapter8/tandibi/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /chapter8/tandibi/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: tandibi_production 11 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | const { VueLoaderPlugin } = require('vue-loader') 3 | const vue = require('./loaders/vue') 4 | 5 | environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin()) 6 | environment.loaders.prepend('vue', vue) 7 | module.exports = environment 8 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/webpack/loaders/vue.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test: /\.vue(\.erb)?$/, 3 | use: [{ 4 | loader: 'vue-loader' 5 | }] 6 | } 7 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/db/migrate/20200224224200_create_pictures.rb: -------------------------------------------------------------------------------- 1 | class CreatePictures < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :pictures do |t| 4 | t.string :caption 5 | t.bigint :post_id, null: false 6 | 7 | t.timestamps 8 | end 9 | 10 | add_foreign_key :pictures, :posts 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /chapter8/tandibi/db/migrate/20200224230539_create_statuses.rb: -------------------------------------------------------------------------------- 1 | class CreateStatuses < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :statuses do |t| 4 | t.string :text, null: false 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /chapter8/tandibi/db/migrate/20200225083408_create_sights.rb: -------------------------------------------------------------------------------- 1 | class CreateSights < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :sights do |t| 4 | t.references :place, null: false, foreign_key: true 5 | t.string :activity_type, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter8/tandibi/lgtm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/lgtm.png -------------------------------------------------------------------------------- /chapter8/tandibi/lgtm2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/lgtm2.gif -------------------------------------------------------------------------------- /chapter8/tandibi/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/lib/assets/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/lib/tasks/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/log/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('tailwindcss')('./app/javascript/css/tailwind.js'), 6 | require('autoprefixer'), 7 | require('postcss-preset-env')({ 8 | autoprefixer: { 9 | flexbox: 'no-2009' 10 | }, 11 | stage: 3 12 | }) 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /chapter8/tandibi/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /chapter8/tandibi/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/public/apple-touch-icon.png -------------------------------------------------------------------------------- /chapter8/tandibi/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/public/favicon.ico -------------------------------------------------------------------------------- /chapter8/tandibi/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /chapter8/tandibi/spec/factories/statuses.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | FactoryBot.define do 11 | factory :status do 12 | text { "MyString" } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter8/tandibi/spec/support/api.rb: -------------------------------------------------------------------------------- 1 | def json_response 2 | JSON.parse response.body 3 | end 4 | -------------------------------------------------------------------------------- /chapter8/tandibi/spec/support/capybara.rb: -------------------------------------------------------------------------------- 1 | require "capybara/rspec" 2 | require "capybara/apparition" 3 | 4 | Capybara.default_driver = :apparition 5 | Capybara.javascript_driver = :apparition 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/spec/support/devise.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include Devise::Test::IntegrationHelpers, 3 | type: :request 4 | end 5 | -------------------------------------------------------------------------------- /chapter8/tandibi/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /chapter8/tandibi/spec/support/job.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include ActiveJob::TestHelper, type: :job 3 | config.include ActiveJob::TestHelper, type: :request 4 | end 5 | -------------------------------------------------------------------------------- /chapter8/tandibi/spec/support/vcr.rb: -------------------------------------------------------------------------------- 1 | require "vcr" 2 | 3 | VCR.configure do |config| 4 | config.cassette_library_dir = "spec/fixtures/vcr_cassettes" 5 | config.hook_into :faraday 6 | end 7 | -------------------------------------------------------------------------------- /chapter8/tandibi/spec/views/home/index.html.erb_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe "home/index.html.erb", type: :view do 4 | pending "add some examples to (or delete) #{__FILE__}" 5 | end 6 | -------------------------------------------------------------------------------- /chapter8/tandibi/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/storage/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/tmp/.keep -------------------------------------------------------------------------------- /chapter8/tandibi/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter8/tandibi/vendor/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /chapter9/tandibi/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /chapter9/tandibi/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.6.5 2 | -------------------------------------------------------------------------------- /chapter9/tandibi/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/app/assets/images/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/app/assets/stylesheets/home.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: https://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/controllers/api/v1/places_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::PlacesController < ApplicationController 2 | def index 3 | keyword = params.fetch(:keyword) 4 | lat = params.fetch(:lat) 5 | lng = params.fetch(:lng) 6 | 7 | PlaceCrawlerJob.perform_later(keyword, lat: lat, lng: lng) 8 | render json: Place::Finder.call(keyword, lat: lat, lng: lng) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | redirect_to(timelines_path) if user_signed_in? 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/decorators/sight_decorator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SightDecorator 4 | def humanized_activity_type 5 | case activity_type 6 | when Sight::CHECKIN then "checked in at" 7 | when Sight::CHECKOUT then "checked out from" 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/helpers/posts_helper.rb: -------------------------------------------------------------------------------- 1 | module PostsHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/helpers/settings/users_helper.rb: -------------------------------------------------------------------------------- 1 | module Settings::UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/javascript/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | 23 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/javascript/css/application.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | @import "common"; 6 | @import "modal"; 7 | @import "home"; 8 | @import "session"; 9 | @import "member"; 10 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/javascript/css/common.css: -------------------------------------------------------------------------------- 1 | .alert { 2 | @apply text-white text-sm text-center font-medium px-4 py-3; 3 | } 4 | 5 | a { 6 | @apply no-underline text-blue-400; 7 | } 8 | 9 | a:hover { 10 | @apply text-blue-500; 11 | } 12 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/javascript/lib/filters.js: -------------------------------------------------------------------------------- 1 | export function truncate(text, length) { 2 | const clamp = "..." 3 | if (text.length <= length) { 4 | return text 5 | } else { 6 | let subString = text.substr(0, length-1) 7 | let lastSpaceIdx = subString.lastIndexOf(' ') 8 | subString = subString.substr(0, lastSpaceIdx) 9 | return subString + clamp 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/jobs/place_crawler_job.rb: -------------------------------------------------------------------------------- 1 | class PlaceCrawlerJob < ApplicationJob 2 | queue_as :default 3 | 4 | def perform(name, lat:, lng:) 5 | Place::Crawler.call(name, lat: lat, lng: lng) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/app/models/concerns/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/app/models/status.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | class Status < ApplicationRecord 11 | validates :text, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/serializers/place_serializer.rb: -------------------------------------------------------------------------------- 1 | class PlaceSerializer < ActiveModel::Serializer 2 | attributes :id, 3 | :locale, 4 | :name, 5 | :place_type, 6 | :coordinates 7 | 8 | def coordinates 9 | coordinate = object.coordinate 10 | { 11 | lng: coordinate.longitude, 12 | lat: coordinate.latitude, 13 | } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/services/application_service.rb: -------------------------------------------------------------------------------- 1 | class ApplicationService 2 | def self.call(*args) 3 | new(*args).call 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/services/bond/rejector.rb: -------------------------------------------------------------------------------- 1 | class Bond::Rejector < ApplicationService 2 | attr_reader :requester, :target_user 3 | private :requester, :target_user 4 | 5 | def initialize(requester, target_user) 6 | @requester = requester 7 | @target_user = target_user 8 | end 9 | 10 | def call 11 | requester.bonds.where(friend: target_user).destroy_all 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/bonds/following.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "timelines/profile_header", user: visited_user %> 2 | 3 | <%= render "bonds/users_list", 4 | users: @bonded_users do |each_user| %> 5 | 6 | <%= render "bonds/bonding_buttons", user: each_user %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/devise/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Password changed

2 | 3 |

Hello <%= @resource.email %>!

4 | 5 |

We're contacting you to notify you that your password has been changed.

6 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/home/_action_button.html.erb: -------------------------------------------------------------------------------- 1 | <% method = local_assigns.fetch(:method, :get) %> 2 | 3 | <%= link_to link, class: "action", method: method do %> 4 | <%= caption %> 5 | <%= evil_icon icon, size: :s, class: "arrow" %> 6 | <% end %> 7 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/layouts/_alert.html.erb: -------------------------------------------------------------------------------- 1 | <% if notice && notice.present? %> 2 | 5 | <% end %> 6 | 7 | <% if alert && alert.present? %> 8 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= render "layouts/header" %> 4 | 5 | 6 | <%= render "layouts/alert" %> 7 | 8 | <%= yield %> 9 | 10 | 11 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/posts/show.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= render "timelines/line", 4 | post: @post, 5 | show_replies: true %> 6 |
7 |
8 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/settings/users/update.html.erb: -------------------------------------------------------------------------------- 1 |

Settings::Users#update

2 |

Find me in app/views/settings/users/update.html.erb

3 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/timelines/_all.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <% @posts.each do |post| %> 3 |
4 | <%= render "timelines/line", post: post %> 5 |
6 | <% end %> 7 |
8 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/timelines/_profile_stat.html.erb: -------------------------------------------------------------------------------- 1 | <% is_active = local_assigns.fetch(:is_active, false) %> 2 | 3 | <%= link_to link_to, class: "stat #{"active" if is_active}" do %> 4 |

<%= count %>

5 |

<%= counter %>

6 | <% end %> 7 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/timelines/index.html.erb: -------------------------------------------------------------------------------- 1 | <%= render("posts/form") %> 2 | 3 | <%= render "timelines/all" %> 4 | -------------------------------------------------------------------------------- /chapter9/tandibi/app/views/timelines/show.html.erb: -------------------------------------------------------------------------------- 1 | <%= render "timelines/profile_header", user: @visited_user %> 2 | 3 | <% if on_self? %> 4 | <%= render("posts/form") %> 5 | <% end %> 6 | 7 | <% if can? current_user, :see_timeline, @visited_user %> 8 | <%= render "timelines/all" %> 9 | <% else %> 10 |

These posts are protected

11 | <% end %> 12 | -------------------------------------------------------------------------------- /chapter9/tandibi/bin/delayed_job: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) 4 | require 'delayed/command' 5 | Delayed::Command.new(ARGV).daemonize 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /chapter9/tandibi/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /chapter9/tandibi/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /chapter9/tandibi/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: tandibi_production 11 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | const { VueLoaderPlugin } = require('vue-loader') 3 | const vue = require('./loaders/vue') 4 | 5 | environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin()) 6 | environment.loaders.prepend('vue', vue) 7 | module.exports = environment 8 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/webpack/loaders/vue.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test: /\.vue(\.erb)?$/, 3 | use: [{ 4 | loader: 'vue-loader' 5 | }] 6 | } 7 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/db/migrate/20200224224200_create_pictures.rb: -------------------------------------------------------------------------------- 1 | class CreatePictures < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :pictures do |t| 4 | t.string :caption 5 | t.bigint :post_id, null: false 6 | 7 | t.timestamps 8 | end 9 | 10 | add_foreign_key :pictures, :posts 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /chapter9/tandibi/db/migrate/20200224230539_create_statuses.rb: -------------------------------------------------------------------------------- 1 | class CreateStatuses < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :statuses do |t| 4 | t.string :text, null: false 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /chapter9/tandibi/db/migrate/20200225083408_create_sights.rb: -------------------------------------------------------------------------------- 1 | class CreateSights < ActiveRecord::Migration[6.0] 2 | def change 3 | create_table :sights do |t| 4 | t.references :place, null: false, foreign_key: true 5 | t.string :activity_type, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /chapter9/tandibi/lgtm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/lgtm.png -------------------------------------------------------------------------------- /chapter9/tandibi/lgtm2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/lgtm2.gif -------------------------------------------------------------------------------- /chapter9/tandibi/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/lib/assets/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/lib/tasks/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/log/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('tailwindcss')('./app/javascript/css/tailwind.js'), 6 | require('autoprefixer'), 7 | require('postcss-preset-env')({ 8 | autoprefixer: { 9 | flexbox: 'no-2009' 10 | }, 11 | stage: 3 12 | }) 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /chapter9/tandibi/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /chapter9/tandibi/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/public/apple-touch-icon.png -------------------------------------------------------------------------------- /chapter9/tandibi/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/public/favicon.ico -------------------------------------------------------------------------------- /chapter9/tandibi/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /chapter9/tandibi/spec/factories/statuses.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: statuses 4 | # 5 | # id :bigint not null, primary key 6 | # text :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | FactoryBot.define do 11 | factory :status do 12 | text { "MyString" } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /chapter9/tandibi/spec/support/api.rb: -------------------------------------------------------------------------------- 1 | def json_response 2 | JSON.parse response.body 3 | end 4 | -------------------------------------------------------------------------------- /chapter9/tandibi/spec/support/capybara.rb: -------------------------------------------------------------------------------- 1 | require "capybara/rspec" 2 | require "capybara/apparition" 3 | 4 | Capybara.default_driver = :apparition 5 | Capybara.javascript_driver = :apparition 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/spec/support/devise.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include Devise::Test::IntegrationHelpers, 3 | type: :request 4 | end 5 | -------------------------------------------------------------------------------- /chapter9/tandibi/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /chapter9/tandibi/spec/support/job.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include ActiveJob::TestHelper, type: :job 3 | config.include ActiveJob::TestHelper, type: :request 4 | end 5 | -------------------------------------------------------------------------------- /chapter9/tandibi/spec/support/vcr.rb: -------------------------------------------------------------------------------- 1 | require "vcr" 2 | 3 | VCR.configure do |config| 4 | config.cassette_library_dir = "spec/fixtures/vcr_cassettes" 5 | config.hook_into :faraday 6 | end 7 | -------------------------------------------------------------------------------- /chapter9/tandibi/spec/views/home/index.html.erb_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe "home/index.html.erb", type: :view do 4 | pending "add some examples to (or delete) #{__FILE__}" 5 | end 6 | -------------------------------------------------------------------------------- /chapter9/tandibi/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/storage/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/tmp/.keep -------------------------------------------------------------------------------- /chapter9/tandibi/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/chapter9/tandibi/vendor/.keep -------------------------------------------------------------------------------- /meta/bookcover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamnoto/learn-rails-6/abc6dddbd7e2531ee80685a7aed22b36511adefe/meta/bookcover.jpg --------------------------------------------------------------------------------