From 7cfb56d4dbb806f13a847894a2fc7eebe4d5a33e Mon Sep 17 00:00:00 2001 From: Alex Bevilacqua Date: Mon, 21 Nov 2022 16:12:09 -0500 Subject: [PATCH 1/2] Clone Rails Tutorial and create variation for Rails 7 --- docs/tutorials.txt | 3 +- ...d-rails.txt => getting-started-rails6.txt} | 11 +- docs/tutorials/getting-started-rails7.txt | 490 ++++++++++++++++++ 3 files changed, 500 insertions(+), 4 deletions(-) rename docs/tutorials/{getting-started-rails.txt => getting-started-rails6.txt} (98%) create mode 100644 docs/tutorials/getting-started-rails7.txt diff --git a/docs/tutorials.txt b/docs/tutorials.txt index 517cd7f463..33ab03954c 100644 --- a/docs/tutorials.txt +++ b/docs/tutorials.txt @@ -10,6 +10,7 @@ Tutorials :titlesonly: tutorials/getting-started-sinatra - tutorials/getting-started-rails + tutorials/getting-started-rails7 + tutorials/getting-started-rails6 tutorials/documents tutorials/common-errors diff --git a/docs/tutorials/getting-started-rails.txt b/docs/tutorials/getting-started-rails6.txt similarity index 98% rename from docs/tutorials/getting-started-rails.txt rename to docs/tutorials/getting-started-rails6.txt index 430749956c..2c8c5f7c53 100644 --- a/docs/tutorials/getting-started-rails.txt +++ b/docs/tutorials/getting-started-rails6.txt @@ -1,6 +1,6 @@ -*********************** -Getting Started (Rails) -*********************** +************************* +Getting Started (Rails 6) +************************* .. default-domain:: mongodb @@ -10,6 +10,11 @@ Getting Started (Rails) :depth: 2 :class: singlecol +.. note:: + + This tutorial is for Ruby on Rails 6. If this is not the version you're using choose + the appropriate tutorial for your Rails version from the navigation menu. + New Application =============== diff --git a/docs/tutorials/getting-started-rails7.txt b/docs/tutorials/getting-started-rails7.txt new file mode 100644 index 0000000000..b67c7abfa5 --- /dev/null +++ b/docs/tutorials/getting-started-rails7.txt @@ -0,0 +1,490 @@ +************************* +Getting Started (Rails 7) +************************* + +.. default-domain:: mongodb + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. note:: + + This tutorial is for Ruby on Rails 7. If this is not the version you're using choose + the appropriate tutorial for your Rails version from the navigation menu. + +New Application +=============== + +This section demonstrates how to create a new Ruby on Rails application using the Mongoid ODM. +By replacing Rails' default `ActiveRecord `_ +adapter with MongoDB's ORM-like library for data access we will create an application similar to the +blog application described in the `Ruby on Rails Getting Started +`_ guide. + +The complete source code for this application can be found in the +`mongoid-demo GitHub repository +`_. + +.. note:: + + This guide assumes basic familiarity with Ruby on Rails. + To learn more about Ruby on Rails, please refer to its `Getting Started + guide `_ or + other Rails guides. + + +Install ``rails`` +----------------- + +We will use a Rails generator to create the application skeleton. +In order to do so, the first step is to install the ``rails`` gem: + +.. code-block:: sh + + gem install rails -v '~> 7' + + +Create New Application +---------------------- + +Use the ``rails`` command to create the application skeleton, as follows: + +.. code-block:: sh + + rails new blog --skip-active-record + cd blog + +We pass ``--skip-active-record`` to request that ActiveRecord is not added +as a dependency, because we will be using Mongoid instead. + +Optionally Skip Tests +````````````````````` + +If you intend to test your application with `RSpec `_, you can instruct the +generator to omit the default Rails test setup by passing ``--skip-test`` +and ``--skip-system-test`` options: + +.. code-block:: sh + + rails new blog --skip-bundle --skip-active-record --skip-test --skip-system-test + cd blog + +Setup Mongoid +------------- + +1. Modify the ``Gemfile`` to add a reference to the +`mongoid `_ gem: + +.. code-block:: ruby + :name: Gemfile + :caption: Gemfile + + gem 'mongoid' + +2. Install gem dependencies: + +.. code-block:: sh + + bundle install + +3. Generate the default `Mongoid configuration `_: + +.. code-block:: sh + + bin/rails g mongoid:config + +This generator will create the ``config/mongoid.yml`` configuration file, +which is used to configure the connection to the MongoDB deployment. +Note that as we are not using ActiveRecord we will not have a ``database.yml`` +file. + +Configure for Self Managed MongoDB +`````````````````````````````````` + +The configuration created in the previous step is suitable when +a MongoDB server is running locally. If you do not already have a +local MongoDB server, `download and install MongoDB +`_. + +While the generated ``mongoid.yml`` will work without modifications, +we recommend reducing the server selection timeout for development. +With this change, the uncommented lines of ``mongoid.yml`` should look +like this: + +.. code-block:: yaml + + development: + clients: + default: + database: blog_development + hosts: + - localhost:27017 + options: + server_selection_timeout: 1 + + +Configure for MongoDB Atlas +``````````````````````````` + +Instead of downloading, installing and running MongoDB locally, you can create +a free MongoDB Atlas account and create a `free MongoDB cluster in Atlas +`_. +Once the cluster is created, follow the instructions in `connect to the cluster +page `_ +to obtain the URI. Use the *Ruby driver 2.5 or later* format. + +Paste the URI into the ``config/mongoid.yml`` file, and comment out the +hosts that are defined. We recommend setting the server selection timeout to 5 +seconds for development environment when using Atlas. + +The uncommented contents of ``config/mongoid.yml`` should look like this: + +.. code-block:: yaml + + development: + clients: + default: + uri: mongodb+srv://user:pass@yourcluster.mongodb.net/blog_development?retryWrites=true&w=majority + options: + server_selection_timeout: 5 + +Run Application +--------------- + +You can now start the application server by running: + +.. code-block:: sh + + bin/rails s + +Access the application by navigating to `localhost:3000 +`_. + + +Add Posts +--------- + +Using the standard Rails scaffolding, Mongoid can generate the necessary +model, controller and view files for our blog so that we can quickly begin +creating blog posts: + +.. code-block:: sh + + bin/rails g scaffold Post title:string body:text + +Navigate to `localhost:3000/posts `_ +to create posts and see the posts that have already been created. + +.. image:: ../img/rails-new-blog.png + :alt: Screenshot of the new blog + + +Add Comments +------------ + +To make our application more interactive, let's add the ability for users to +add comments to our posts. + +Create the ``Comment`` model: + +.. code-block:: sh + + bin/rails g scaffold Comment name:string message:string post:belongs_to + +Open the ``Post`` model file, ``app/models/post.rb``, and add a ``has_many`` +association for the comments: + +.. code-block:: ruby + :name: app/models/post.rb + :caption: app/models/post.rb + + class Post + include Mongoid::Document + include Mongoid::Timestamps + field :title, type: String + field :body, type: String + + has_many :comments, dependent: :destroy + end + +Open ``app/views/posts/show.html.erb`` and add +a section rendering existing comments and prompting to leave a new comment: + +.. code-block:: erb + :name: app/views/posts/show.html.erb + :caption: app/views/posts/show.html.erb + +
+
+

+ <%= @post.comments.count %> Comments +

+ <%= render @post.comments %> +
+
+

Leave a reply

+ <%= render partial: 'comments/form', locals: { comment: @post.comments.build } %> +
+
+
+ +Open ``app/views/comments/_form.html.erb`` and change the type of field for ``:message`` +from ``text_field`` to ``text_area``, as well as the type of field for +``:post_id`` from ``text_field`` to ``hidden_field``. The result +should look like this: + +.. code-block:: erb + :name: app/views/comments/_form.html.erb + :caption: app/views/comments/_form.html.erb + + <%= form_with(model: comment, local: true) do |form| %> + <% if comment.errors.any? %> +
+

<%= pluralize(comment.errors.count, "error") %> prohibited this comment from being saved:

+ +
    + <% comment.errors.full_messages.each do |message| %> +
  • <%= message %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= form.label :name %> + <%= form.text_field :name %> +
+ +
+ <%= form.label :message %> + <%= form.text_area :message %> +
+ +
+ <%= form.hidden_field :post_id %> +
+ +
+ <%= form.submit %> +
+ <% end %> + +Next replace ``app/view/comments/_comment.html.erb`` with the following contents: + +.. code-block:: erb + :name: app/views/comments/_comment.html.erb + :caption: app/views/comments/_comment.html.erb + +

+ <%= comment.name %>: + <%= comment.message %> + <%= link_to 'Delete', [comment], + data: { + "turbo-method": :delete, + "turbo-confirm": 'Are you sure?' + } %> +

+ + +You should now be able to leave comments for the posts: + +.. image:: ../img/rails-blog-new-comment.png + :alt: Screenshot of the blog with a new comment being added + + +Existing Application +==================== + +Follow these steps to switch an existing Ruby on Rails application to use +Mongoid instead of ActiveRecord. + +Dependencies +------------ + +Remove or comment out any RDBMS libraries like ``sqlite``, ``pg`` etc. +mentioned in ``Gemfile``, and add ``mongoid``: + +.. code-block:: ruby + :name: Gemfile + :caption: Gemfile + + gem 'mongoid', '~> 7.0.5' + +.. note:: + + Mongoid 7.0.5 or higher is required to use Rails 6.0. + +Install gem dependencies: + +.. code-block:: sh + + bundle install + +Loaded Frameworks +----------------- + +Examine ``config/application.rb``. If it is requiring all components of Rails +via ``require 'rails/all'``, change it to require individual frameworks: + +.. code-block:: ruby + :name: config/application.rb + :caption: config/application.rb + + # Remove or comment out + #require "rails/all" + + # Add this require instead of "rails/all": + require "rails" + + # Pick the frameworks you want: + require "active_model/railtie" + require "active_job/railtie" + require "action_controller/railtie" + require "action_mailer/railtie" + # require "action_mailbox/engine" + # require "action_text/engine" + require "action_view/railtie" + require "action_cable/engine" + require "sprockets/railtie" + require "rails/test_unit/railtie" + + # Remove or comment out ActiveRecord and ActiveStorage: + # require "active_record/railtie" + # require "active_storage/engine" + +.. note:: + + At this time ActiveStorage requires ActiveRecord and is not usable with + Mongoid. + +ActiveRecord Configuration +-------------------------- + +Review all configuration files (``config/application.rb``, +``config/environments/{development,production.test}.rb``) and remove or +comment out any references to ``config.active_record`` and +``config.active_storage``. + +Stop Spring +----------- + +If your application is using Spring, which is the default on Rails 6, +Spring must be stopped after changing dependencies or configuration. + +.. code-block:: sh + + ./bin/spring stop + +.. note:: + + Sometimes running ``./bin/spring stop`` claims to stop Spring, but does + not. Verify that all Spring processes are terminated before proceeding. + +.. note:: + + Sometimes Spring tries to load ActiveRecord even when the application + contains no ActiveRecord references. If this happens, add an ActiveRecord + adapter dependency such as ``sqlite3`` to your ``Gemfile`` so that + ActiveRecord may be completely loaded or remove Spring from your + application. + +Mongoid Configuration +--------------------- + +Generate the default Mongoid configuration: + +.. code-block:: sh + + bin/rails g mongoid:config + +This generator will create the ``config/mongoid.yml`` configuration file, +which is used to configure the connection to the MongoDB deployment. + +Review the sections `Run MongoDB Locally`_ and `Use MongoDB Atlas`_ +to decide how you would like to deploy MongoDB, and adjust Mongoid +configuration (``config/mongoid.yml``) to match. + +Adjust Models +------------- + +If your application already has models, these will need to be changed when +migrating from ActiveRecord to Mongoid. + +ActiveRecord models derive from ``ApplicationRecord`` and do not have +column definitions. Mongoid models generally have no superclass but must +include ``Mongoid::Document``, and usually define the fields explicitly +(but :ref:`dynamic fields ` may also be used instead of +explicit field definitions). + +For example, a bare-bones Post model may look like this in ActiveRecord: + +.. code-block:: ruby + :name: app/models/post.rb + :caption: app/models/post.rb + + class Post < ApplicationRecord + has_many :comments, dependent: :destroy + end + +The same model may look like this in Mongoid: + +.. code-block:: ruby + :name: app/models/post.rb + :caption: app/models/post.rb + + class Post + include Mongoid::Document + + field :title, type: String + field :body, type: String + + has_many :comments, dependent: :destroy + end + +Or like this with dynamic fields: + +.. code-block:: ruby + :name: app/models/post.rb + :caption: app/models/post.rb + + class Post + include Mongoid::Document + include Mongoid::Attributes::Dynamic + + has_many :comments, dependent: :destroy + end + +Mongoid does not utilize ActiveRecord migrations, since MongoDB does not +require a schema to be defined prior to storing data. + +Data Migration +-------------- + +If you already have data in a relational database that you would like to +transfer to MongoDB, you will need to perform a data migration. As noted +above, no schema migration is necessary because MongoDB does not require +a predefined schema to store the data. + +The migration tools are often specific to the data being migrated because, +even though Mongoid supports a superset of ActiveRecord associations, +the way that model references are stored in collections differs between +Mongoid and ActiveRecord. With that said, MongoDB has +some resources on migrating from an RDBMS to MongoDB such as the +`RDBMS to MongoDB Migration Guide `_ and +`Modernization Guide `_. + + +Rails API +--------- + +The process for creating a Rails API application with Mongoid is the same +as when creating a regular application, with the only change being the +``--api`` parameter to ``rails new``. Migrating a Rails API application to +Mongoid follows the same process described above for regular Rails applications. + +A complete Rails API application similar to the one described in this tutorial +can be found in the `mongoid-demo GitHub repository +`_. From d7f2d7bef868d6a83ec5aeb76ad564cc50dd9c84 Mon Sep 17 00:00:00 2001 From: Alex Bevilacqua Date: Tue, 22 Nov 2022 14:52:37 -0500 Subject: [PATCH 2/2] Update Existing Application docs for Rails 7 --- docs/tutorials/getting-started-rails7.txt | 112 +++++++++------------- 1 file changed, 45 insertions(+), 67 deletions(-) diff --git a/docs/tutorials/getting-started-rails7.txt b/docs/tutorials/getting-started-rails7.txt index b67c7abfa5..d72b522301 100644 --- a/docs/tutorials/getting-started-rails7.txt +++ b/docs/tutorials/getting-started-rails7.txt @@ -298,24 +298,26 @@ You should now be able to leave comments for the posts: Existing Application ==================== -Follow these steps to switch an existing Ruby on Rails application to use -Mongoid instead of ActiveRecord. +Mongoid can be easily added to an existing Rails application and run alongside other ActiveRecord +adapters. If this is your use case, updating dependencies and populating the configuration file will +allow you to start using MongoDB within your application. + +To switch an existing Ruby on Rails application to use Mongoid instead of ActiveRecord additional +configuration changes will be required, as described below. Dependencies ------------ -Remove or comment out any RDBMS libraries like ``sqlite``, ``pg`` etc. -mentioned in ``Gemfile``, and add ``mongoid``: +First, the ``mongoid`` gem will need to be added your ``Gemfile``. .. code-block:: ruby :name: Gemfile :caption: Gemfile - gem 'mongoid', '~> 7.0.5' - -.. note:: + gem 'mongoid' - Mongoid 7.0.5 or higher is required to use Rails 6.0. +If Mongoid will be the **only** database adapter, remove or comment out any RDBMS libraries +like ``sqlite`` or ``pg`` mentioned in the ``Gemfile``. Install gem dependencies: @@ -323,11 +325,29 @@ Install gem dependencies: bundle install +Mongoid Configuration +--------------------- + +Generate the default Mongoid configuration: + +.. code-block:: sh + + bin/rails g mongoid:config + +This generator will create the ``config/mongoid.yml`` configuration file, +which is used to configure the connection to the MongoDB deployment. + +Review the sections `Configure for Self Managed MongoDB`_ and `Configure for MongoDB Atlas`_ +to decide how you would like to deploy MongoDB, and adjust the Mongoid +configuration (``config/mongoid.yml``) to match. + Loaded Frameworks ----------------- Examine ``config/application.rb``. If it is requiring all components of Rails -via ``require 'rails/all'``, change it to require individual frameworks: +via ``require 'rails/all'``, change it to require individual frameworks. To verify the contents of +``rails/all`` for your version see the `Github Repository +`_: .. code-block:: ruby :name: config/application.rb @@ -336,29 +356,26 @@ via ``require 'rails/all'``, change it to require individual frameworks: # Remove or comment out #require "rails/all" - # Add this require instead of "rails/all": + # Add the following instead of "rails/all": require "rails" - # Pick the frameworks you want: - require "active_model/railtie" - require "active_job/railtie" - require "action_controller/railtie" - require "action_mailer/railtie" - # require "action_mailbox/engine" - # require "action_text/engine" - require "action_view/railtie" - require "action_cable/engine" - require "sprockets/railtie" - require "rails/test_unit/railtie" - - # Remove or comment out ActiveRecord and ActiveStorage: - # require "active_record/railtie" - # require "active_storage/engine" + # require "active_record/railtie" rescue LoadError + # require "active_storage/engine" rescue LoadError + require "action_controller/railtie" rescue LoadError + require "action_view/railtie" rescue LoadError + require "action_mailer/railtie" rescue LoadError + require "active_job/railtie" rescue LoadError + require "action_cable/engine" rescue LoadError + # require "action_mailbox/engine" rescue LoadError + # require "action_text/engine" rescue LoadError + require "rails/test_unit/railtie" rescue LoadError -.. note:: +.. warning:: - At this time ActiveStorage requires ActiveRecord and is not usable with - Mongoid. + Due to their reliance on ActiveRecord, `ActionText `_, + `ActiveStorage `_ and + `ActionMailbox `_ cannot be used + with Mongoid. ActiveRecord Configuration -------------------------- @@ -368,45 +385,6 @@ Review all configuration files (``config/application.rb``, comment out any references to ``config.active_record`` and ``config.active_storage``. -Stop Spring ------------ - -If your application is using Spring, which is the default on Rails 6, -Spring must be stopped after changing dependencies or configuration. - -.. code-block:: sh - - ./bin/spring stop - -.. note:: - - Sometimes running ``./bin/spring stop`` claims to stop Spring, but does - not. Verify that all Spring processes are terminated before proceeding. - -.. note:: - - Sometimes Spring tries to load ActiveRecord even when the application - contains no ActiveRecord references. If this happens, add an ActiveRecord - adapter dependency such as ``sqlite3`` to your ``Gemfile`` so that - ActiveRecord may be completely loaded or remove Spring from your - application. - -Mongoid Configuration ---------------------- - -Generate the default Mongoid configuration: - -.. code-block:: sh - - bin/rails g mongoid:config - -This generator will create the ``config/mongoid.yml`` configuration file, -which is used to configure the connection to the MongoDB deployment. - -Review the sections `Run MongoDB Locally`_ and `Use MongoDB Atlas`_ -to decide how you would like to deploy MongoDB, and adjust Mongoid -configuration (``config/mongoid.yml``) to match. - Adjust Models -------------