Skip to content

Commit c253bf7

Browse files
committed
Refactor Ruby Couchbase ORM quickstart tutorial for clarity and accuracy. Removed redundant gem installation instructions, updated image paths for consistency, and improved explanations for connection handling and CRUD operations.
1 parent fa8cd49 commit c253bf7

File tree

1 file changed

+35
-47
lines changed

1 file changed

+35
-47
lines changed

tutorial/markdown/ruby/ruby-couchbase-orm/quickstart-ruby-couchbase-orm.md

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ To run this prebuilt project, you will need:
3838

3939
- [Load travel-sample bucket in Couchbase Capella](https://docs.couchbase.com/cloud/clusters/data-service/import-data-documents.html#import-sample-data)
4040

41-
4241
### Couchbase Capella Configuration
4342

4443
When running Couchbase using [Capella](https://cloud.couchbase.com/), the following prerequisites need to be met.
@@ -65,22 +64,10 @@ gem install bundler
6564
bundle install
6665
```
6766

68-
The application uses the following gems and needs to be installed globally even though they are specified in the `Gemfile`.
69-
70-
```shell
71-
gem install rails
72-
gem install rspec
73-
gem install rubocop
74-
gem install rswag
75-
gem install couchbase
76-
gem install couchbase-orm
77-
```
78-
79-
> Refer to the [instructions in the SDK](https://github.com/couchbase/couchbase-ruby-client#installation) for more info. -->
67+
> Refer to the [instructions in the SDK](https://github.com/couchbase/couchbase-ruby-client#installation) for more info.
8068
8169
### Setup Database Configuration
8270

83-
8471
To use Couchbase ORM in your Ruby application, you need to configure the connection settings for your Couchbase Server instance. Couchbase ORM provides a simple way to configure the connection.
8572

8673
1. **Rails Applications**:
@@ -164,7 +151,7 @@ Once the app is up and running, open http://localhost:3000/api-docs to test the
164151

165152
Once the application starts, you can see the details of the application on the logs.
166153

167-
![Application Startup](app_startup.png)
154+
![Application Startup](./app_startup.png)
168155

169156
The application will run on port 3000 of your local machine (http://localhost:3000). You will find the interactive Swagger documentation of the API if you go to the URL in your browser. Swagger documentation is used in this demo to showcase the different API end points and how they can be invoked. More details on the Swagger documentation can be found in the [appendix](#swagger-documentation).
170157

@@ -174,7 +161,7 @@ The application will run on port 3000 of your local machine (http://localhost:30
174161

175162
For this tutorial, we use three collections, `airport`, `airline` and `route` that contain sample airports, airlines and airline routes respectively. The route collection connects the airports and airlines as seen in the figure below. We use these connections in the quickstart to generate airports that are directly connected and airlines connecting to a destination airport. Note that these are just examples to highlight how you can use SQL++ queries to join the collections.
176163

177-
![img](travel_sample_data_model.png)
164+
![Travel Sample Data Model](./travel_sample_data_model.png)
178165

179166
## Let Us Review the Code
180167

@@ -250,9 +237,9 @@ In `routes.rb`, we define the routes for the application including the API route
250237
251238
We have the Couchbase SDK operations defined in the `CouchbaseClient` class inside the `config/initializers/couchbase.rb` file.
252239
253-
We recommend creating a single Couchbase connection when your application starts up, and sharing this instance throughout your application. If you know at startup time which buckets, scopes, and collections your application will use, we recommend obtaining them from the Cluster at startup time and sharing those instances throughout your application as well.
240+
We recommend creating a single Couchbase connection when your application starts up and reusing this connection throughout your application. This approach improves performance by avoiding the overhead of creating new connections for each request. If you know which buckets, scopes, and collections your application will use, obtain these references at startup and share them throughout your application as well.
254241
255-
In this application, we have created the connection object in `config/initializers/couchbase.rb` and we use this object in all of our APIs. The object is initialized in `config/initializers/couchbase.rb`. We have also stored the reference to our bucket, `travel-sample` and the scope, `inventory` in the connection object.
242+
In this application, we have created the connection object in `config/initializers/couchbase.rb` and use it in all of our APIs. We have also stored references to the `travel-sample` bucket and the `inventory` scope in global constants for easy access.
256243
257244
```rb
258245
require 'couchbase'
@@ -331,11 +318,11 @@ We will be setting up a REST API to manage airline documents.
331318
- [Airline List](#list-airline) – Get all airlines. Optionally filter the list by country
332319
- [Direct Connections](#direct-connections) - Get a list of airlines directly connected to the specified airport
333320

334-
For CRUD operations, we will use the [Key-Value operations](https://docs.couchbase.com/ruby-sdk/current/howtos/kv-operations.html) that are built into the Couchbase SDK to create, read, update, and delete a document. Every document will need an ID (similar to a primary key in other databases) to save it to the database. This ID is passed in the URL. For other end points, we will use [SQL++](https://docs.couchbase.com/ruby-sdk/current/howtos/n1ql-queries-with-sdk.html) to query for documents.
321+
For CRUD operations, we will use [Key-Value operations](https://docs.couchbase.com/ruby-sdk/current/howtos/kv-operations.html) using the SDK. Every document will need an ID (similar to a primary key in other databases) to save it to the database. This ID is passed in the URL. For other end points, we will use [SQL++](https://docs.couchbase.com/ruby-sdk/current/howtos/n1ql-queries-with-sdk.html) to query for documents.
335322

336323
### Airline Document Structure
337324

338-
Our airline document will have an airline name, IATA code, ICAO code, callsign, and country. For this demo, we will store all airline information in one document in the `airline` collection in the `travel-sample` bucket.
325+
Our airline document will have an airline name, IATA code, ICAO code, callsign, and country. For this demo, each airline's information is stored as a separate document in the `airline` collection in the `travel-sample` bucket.
339326

340327
```json
341328
{
@@ -347,8 +334,7 @@ Our airline document will have an airline name, IATA code, ICAO code, callsign,
347334
}
348335
```
349336

350-
### POST Airline
351-
337+
### POST Airline
352338

353339
```rb
354340
# frozen_string_literal: true
@@ -376,7 +362,7 @@ module Api
376362
render json: { error: 'Internal server error', message: e.message }, status: :internal_server_error
377363
end
378364
end
379-
...
365+
...
380366

381367
end
382368
end
@@ -387,6 +373,7 @@ In the above code, we first create an instance of the `Airline` class using the
387373
```rb
388374
# frozen_string_literal: true
389375

376+
# Airline model
390377
class Airline
391378
attr_accessor :name, :iata, :icao, :callsign, :country
392379

@@ -419,7 +406,7 @@ class Airline
419406
new(formatted_attributes)
420407
end
421408

422-
...
409+
...
423410
end
424411

425412
```
@@ -428,8 +415,6 @@ In the above code, we first check if all the required fields are present in the
428415

429416
### GET Airline
430417

431-
Navigate to the `show` method in the `AirlinesController` class in the `airlines_controller.rb` file. We only need the airline document ID or our key from the user to retrieve a particular airline document using a key-value operation which is passed in the `find` method. The result is converted into a JSON object using the `to_json` method.
432-
433418
```rb
434419
# GET /api/v1/airlines/{id}
435420
def show
@@ -445,7 +430,7 @@ Navigate to the `show` method in the `AirlinesController` class in the `airlines
445430
end
446431
```
447432

448-
The `find` method in the `Airline` class is used to fetch the document from the database using the key. If the document is found, we return the document with a status of 200. If the document is not found, we return a not found status of 404. If there is any other error, we return an internal server error status of 500.
433+
In the above code, we retrieve the airline document using the `show` method in the controller. The `@airline` instance variable is set by the `set_airline` before_action callback. If the airline is found, we return the airline document with a status of 200. If the airline is not found, we return a not found status of 404. If there is any other error, we return an internal server error status of 500.
449434

450435
```rb
451436
def self.find(id)
@@ -460,8 +445,6 @@ In the `find` method, we use the `get` method to fetch the document from the dat
460445

461446
### PUT Airline
462447

463-
Navigate to the `update` method in the `AirlinesController` class in the `airlines_controller.rb` file. We only need the airline document ID or our key from the user to update a particular airline document using a key-value operation which is passed in the `update` method. The result is converted into a JSON object using the `to_json` method.
464-
465448
```rb
466449
# PUT /api/v1/airlines/{id}
467450
def update
@@ -474,7 +457,7 @@ Navigate to the `update` method in the `AirlinesController` class in the `airlin
474457
end
475458
```
476459

477-
Inn the above code, we first create an instance of the `Airline` class using the `update` method. We pass the ID and the airline data to the `update` method. If the airline is updated successfully, we return the airline document with a status of 200. If there are any missing fields in the request, we return a bad request status of 400. If there is any other error, we return an internal server error status of 500.
460+
In the above code, we first create an instance of the `Airline` class using the `update` method. We pass the ID and the airline data to the `update` method. If the airline is updated successfully, we return the airline document with a status of 200. If there are any missing fields in the request, we return a bad request status of 400. If there is any other error, we return an internal server error status of 500.
478461

479462
```rb
480463
def update(id, attributes)
@@ -507,8 +490,6 @@ In the `update` method, we first check if all the required fields are present in
507490

508491
### DELETE Airline
509492

510-
Navigate to the `destroy` method in the `AirlinesController` class in the `airlines_controller.rb` file. We only need the airline document ID or our key from the user to delete a particular airline document using a key-value operation which is passed in the `destroy` method.
511-
512493
```rb
513494
# DELETE /api/v1/airlines/{id}
514495
def destroy
@@ -539,8 +520,6 @@ end
539520

540521
### List Airlines
541522

542-
Navigate to the `index` method in the `AirlinesController` class in the `airlines_controller.rb` file. We only need the country, limit, and offset values from the user to retrieve a list of airline documents using a SQL++ query. The result is converted into a JSON object using the `to_json` method.
543-
544523
```rb
545524
# GET /api/v1/airlines/list
546525
def index
@@ -562,7 +541,6 @@ Navigate to the `index` method in the `AirlinesController` class in the `airline
562541

563542
In the above code, we first get the values for the country, limit, and offset from the request parameters. We then call the `all` method in the `Airline` class to fetch the list of airlines. If the list is empty, we return a status of 200 with a message. If the list is not empty, we return a status of 200 with the list of airlines. If there is any other error, we return an internal server error status of 500.
564543

565-
566544
```rb
567545
def self.all(country = nil, limit = 10, offset = 0)
568546
bucket_name = 'travel-sample'
@@ -606,27 +584,37 @@ end
606584

607585
We have defined integration tests using [RSpec](https://rspec.info/) for all the API end points. The integration tests use the same database configuration as the application. For the tests, we perform the operation using the API and confirm the results by checking the documents in the database. For example, to check the creation of the document by the API, we would call the API to create the document and then read the same document directly from the database using the CouchbaseClient and compare them. After the tests, the documents are cleaned up.
608586

609-
To run the tests, use the following commands:
587+
To run all integration tests, use the following command:
610588

611589
```bash
612-
rspec test/integration/airlines_spec.rb
613-
rspec test/integration/airports_spec.rb
614-
rspec test/integration/routes_spec.rb
590+
bundle exec rspec test/integration/
615591
```
616592

617593
## Appendix
618594

619595
### Extending API by Adding New Entity
620596

621-
If you would like to add another entity to the APIs, these are the steps to follow:
597+
If you would like to add another entity to the APIs, follow these steps:
598+
599+
1. **Create the new collection in Couchbase**: Create the new entity (collection) in the Couchbase bucket. You can create the collection using the [SDK](https://docs.couchbase.com/sdk-api/couchbase-ruby-client/Couchbase/Collection.html#create_collection-instance_method) or via the [Couchbase Server interface](https://docs.couchbase.com/server/current/manage/manage-settings/manage-collections.html).
600+
601+
2. **Create the model**: Create a new model file in the `app/models/` folder (e.g., `app/models/hotel.rb`). Define the model class with attributes and methods for CRUD operations similar to the `Airline` model.
602+
603+
3. **Create the controller**: Create a new controller file in the `app/controllers/api/v1/` folder (e.g., `app/controllers/api/v1/hotels_controller.rb`). Implement the CRUD action methods (index, show, create, update, destroy) similar to `airlines_controller.rb`.
604+
605+
4. **Add routes**: Open `config/routes.rb` and add the new routes for your entity within the `namespace :api` and `namespace :v1` blocks. For example:
606+
607+
```ruby
608+
resources :hotels
609+
```
610+
611+
5. **Add integration tests**: Create a new test file in the `test/integration/` folder (e.g., `test/integration/hotels_spec.rb`) to test your API endpoints similar to `airlines_spec.rb`.
612+
613+
6. **Add Swagger documentation**: Create a new spec file in the `spec/requests/api/v1/` folder (e.g., `spec/requests/api/v1/hotels_spec.rb`) for Swagger documentation similar to the airlines spec.
614+
615+
7. **Generate Swagger docs**: Run the command `rake rswag:specs:swaggerize` to generate the Swagger documentation.
622616

623-
- Create the new entity (collection) in the Couchbase bucket. You can create the collection using the [SDK](https://docs.couchbase.com/sdk-api/couchbase-ruby-client/Couchbase/Collection.html#create_collection-instance_method) or via the [Couchbase Server interface](https://docs.couchbase.com/server/current/manage/manage-settings/manage-collections.html).
624-
- Define the routes in a new file in the `api` folder similar to the existing routes like `airline_controller.rb`.
625-
- Add the new routes to the application in `routes.rb`.
626-
- Add the tests for the new routes in a new file in the `test/integration/api/v1` folder similar to `airlines_spec.rb`.
627-
- For Swagger documentation, add the configuration in the `spec/request/api/v1` folder similar to `airlines_spec.rb`.
628-
- Run the command `rake rswag:specs:swaggerize` to generate the Swagger documentation.
629-
- The new entity is now ready to be used in the API.
617+
Your new entity is now ready to be used in the API.
630618

631619
### Running Self Managed Couchbase Cluster
632620

0 commit comments

Comments
 (0)