Skip to content

Correct the grammar in the README.md file #271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 22 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@

Implements a Rails engine for Learning Content Management System (LCMS) applications.

Our initial goal is gathering the common code among the current LCMS implementations
(Odell, Unbound ED and OpenSciEd) and provide a unified codebase that can be maintained and developed
Our initial goal is to gather the standard code among the current LCMS implementations
(Odell, Unbound ED, and OpenSciEd) and provide a unified codebase that can be maintained and developed
separately, simplifying the client applications in the process.

## Requirements
- Ruby 2.7.x
- Rails 6.1 or higher
- Postgres 9.6 or higher

Note: if you're using Node version >= 17.x you'll need to set `NODE_OPTIONS=--openssl-legacy-provider` to be able to compile lcms-engine assets.
Note: if you're using Node version >= 17.x, you'll need to set `NODE_OPTIONS=--openssl-legacy-provider` to be able to compile lcms-engine assets.

## Current development

Expand All @@ -25,42 +25,24 @@ Note: if you're using Node version >= 17.x you'll need to set `NODE_OPTIONS=--op

## Guidelines

The following are a few recommendations and guidelines to keep in mind when modifying code in the
engine as well as making the client projects aware of these changes.
The following are a few recommendations and guidelines to keep in mind when modifying code in the engine, as well as making the client projects aware of these changes.

## Use of separate gems

In our opinion, the creation of separate gems in a given project only makes sense when the features
to be extracted have enough weight to justify a separate development cycle, away from the original
project, and are useful to more than one application at the same time. When that does not happen,
the argument in favor of multiple gems per project becomes less convincing, and the downsides of
this approach - like keeping compatibility with the dependencies or being forced to manage different
versions - are more evident and, thus, make development harder for a minor benefit.
In our opinion, the creation of separate gems in a given project only makes sense when the features to be extracted have enough weight to justify a separate development cycle, away from the original project, and are useful to more than one application at the same time. When that does not happen, the argument in favor of multiple gems per project becomes less convincing, and the downsides of this approach, like keeping compatibility with the dependencies or being forced to manage different versions, are more evident and, thus, make development harder for a minor benefit.

Rails supports, and even encourages, a monolithic approach when developing web applications, so it's
always going to be easier to work with it if you adhere to this type of architecture.
Rails supports, and even encourages, a monolithic approach when developing web applications, so it's always going to be easier to work with it if you adhere to this type of architecture.

Whenever you're thinking about extracting some piece of code that's only relevant to your project
into a gem, you can consider either moving it to the engine if it's a common LCMS feature that can
potentially be used by other client projects. Otherwise just keep it inside your project; perhaps
in a separate module or namespace so that it does not get tangled with your regular application code.
Creating a new gem is probably not worth the effort and should only be considered in a few specific
cases.
Whenever you're thinking about extracting some piece of code that's only relevant to your project into a gem, you can consider either moving it to the engine if it's a common LCMS feature that can potentially be used by other client projects. Otherwise, just keep it inside your project; perhaps in a separate module or namespace so that it does not get tangled with your regular application code. Creating a new gem is probably not worth the effort and should only be considered in a few specific cases.

### Override and extension

When the features provided by the engine are not enough in your client application or you need to
perform some kind of customization or improvement, it's important to distinguish the type of asset
you're trying to customize and the volume of the changes involved.
When the features provided by the engine are not enough in your client application or you need to perform some kind of customization or improvement, it's important to distinguish the type of asset you're trying to customize and the volume of the changes involved.

For regular Ruby classes and modules, we suggest sticking to the recommended practices defined in
the official [Rails guide for engines](https://guides.rubyonrails.org/engines.html#improving-engine-functionality)
For regular Ruby classes and modules, we suggest sticking to the recommended practices defined in the official [Rails guide for engines](https://guides.rubyonrails.org/engines.html#improving-engine-functionality)
which, for the most part, use the [Decorator pattern](https://en.wikipedia.org/wiki/Decorator_pattern).

* For small changes or refinements you can create a new decorator class inside the `app/decorators`
folder, and use `class_eval` or `module_eval` to override the methods that you want. You can see a
few examples of this technique in the latest changes added to [OpenSciEd](https://github.com/learningtapestry/openscied-lcms/tree/engine-integration/app/decorators)
and [Odell](https://github.com/learningtapestry/odell-lcms/tree/engine-integration/app/decorators)
* For small changes or refinements, you can create a new decorator class inside the `app/decorators` folder, and use `class_eval` or `module_eval` to override the methods that you want. You can see a few examples of this technique in the latest changes added to [OpenSciEd](https://github.com/learningtapestry/openscied-lcms/tree/engine-integration/app/decorators) and [Odell](https://github.com/learningtapestry/odell-lcms/tree/engine-integration/app/decorators)
* When changes are bigger or have a much larger impact on the target class or module, it's better to
include a new module that contains your overrides. Again, the Rails guide suggests using
`ActiveSupport::Concern`, which simplifies things a bit, although a regular Ruby module would also
Expand All @@ -70,11 +52,11 @@ After that, you're free to add new methods or override the ones from the module.
You can see examples of an [extracted module](https://github.com/learningtapestry/lcms-engine/blob/master/lib/concerns/doc_template/template.rb)
and a [class including it](https://github.com/learningtapestry/odell-lcms/blob/engine-integration/lib/doc_template/template.rb).
* Finally, as a last resort, if the customizations you're performing differ a lot from the default
behaviour, you can consider overriding completely the class by just leaving a file with the same
behaviour, you can consider overriding the class completely by just leaving a file with the same
name in the same path. Rails will always give preference to classes inside your project in the
loading phase.

Other kinds of assets, like ERB views, images, stylesheets or javascript files, can not be
Other kinds of assets, like ERB views, images, stylesheets, or JavaScript files, can not be
overridden as easily as Ruby classes and modules, but you can always provide your own versions of
the same files, overwriting the ones provided by the engine.

Expand Down Expand Up @@ -115,16 +97,16 @@ Mount the engine in the `routes.rb`
```ruby
mount Lcms::Engine::Engine, at: '/lcms'
```
Pay attention that adding route alias is not supported. That said you **can't** mount the engine as follow:
Pay attention that adding a route alias is not supported. That said, you **can't** mount the engine as follows:
```ruby
mount Engine, at: '/engine', as: :engine
````

If you need to redefine devise routes set up env `DEVISE_ROUTES_REDEFINED` as true and define devise related routes at host app.
If you need to redefine devise routes, set up env `DEVISE_ROUTES_REDEFINED` as true and define devise-related routes at the host app.

### Host app routes

When host app has its own routes on upper than engine level:
When the host app has its own routes on upper than engine level:
```ruby
Lcms::Engine::Engine.routes.draw do
devise_for :users, class_name: 'Lcms::Engine::User',
Expand All @@ -151,7 +133,7 @@ devise_scope :user do
delete '/register', to: 'lcms/engine/registrations#destroy'
end
```
When host app is ok with `/lcms` devise routes but want to redefine paths after that:
When the host app is ok with `/lcms` devise routes, but want to redefine paths after that:
```ruby
Lcms::Engine::Engine.routes.draw do
devise_for :users, class_name: 'Lcms::Engine::User',
Expand All @@ -173,25 +155,24 @@ end

### Migrations

All migrations included in the gem are already available for you to run from inside host application.
All migrations included in the gem are already available for you to run from inside the host application.

### Using with Host app
### Using with the Host app

You need to run special rake task if default routes were overridden
You need to run a special rake task if the default routes were overridden
```bash
$ bundle exec rake js-routes:generate
```

## Developing and testing

You need to create `/spec/dummy/.env.test` file to be able to use Rails console
inside dummy app.
You need to create `/spec/dummy/.env.test` file to be able to use the Rails console inside the dummy app.

To be able to to run specs you need to create `/spec/dummy/.env.test` file and add there variables for database
To be able to run specs, you need to create a `/spec/dummy/.env.test` file and add variables for database
connection (see `spec/dummy/.env` as a template)

`chromedriver` is required to run feature specs. You may find OS-specific instructions [here](https://sites.google.com/a/chromium.org/chromedriver/getting-started).
For macOS it can be installed with Homebrew:
For macOS, it can be installed with Homebrew:

```bash
$ brew tap homebrew/cask
Expand Down