I have mountable rails engine Users:
users/
...
features/
...
specs/
dummy/
controllers/
models/
factories/
...
I have a client app MySite, which uses the Users engine:
my_site/
app/
...
features/
...
specs/
controllers/
models/
factories/
...
Gemfile
Gemfile:
gem "users", git: "..."
Is it possible to run engine rspec/cucumber tests in the MySite app instead of the mock?
If so, what is the best way?
You should not do this for two reasons:
The User engine is its own project. It should work in isolation in a certain way. Adding these tests to any project the User engine is included in does not make sense. Why not run all the specs of all the gems you include in your project as well?
If you have specific acceptance criteria for your application, add cucumbers for that to your project. That way, if you decide to ditch the User engine in the future with something else, you can still verify your application behaving as expected. If you'd included the cucumbers from the engine, then those criteria would have been lost as well.
Related
This is my first time interaction with a rails plugin and I'm unable to wrap my head around how this thing works. I'm going to make a rails plugin/engine. I want to include this plugin in my rails application(a different project), how can I do it? I found this which suggests to
At the root of this brand new engine's directory lives a plugin_name.gemspec file. When you include the engine into an application later on, you will do so with this line in the Rails application's Gemfile:
gem 'plugin_name', path: 'engines/plugin_name'
My question is that how exactly do I do it? I mean when I create a rails application I do not find any engines directory in the folder structure. And also which directories from the plugin project do I have to place in the engines/ directory?
I created a plugin by doing
rails plugin new plugin_name --mountable
and it generated following files/directories:
|-app/
|-bin/
|-config/
|-demo_project.gemspec
|-Gemfile
|-Gemfile.lock
|-lib/
|-MIT-LICENSE
|-Rakefile
|-README.md
|-test
|-dummy
|-(contains a rails application)
Now once I'm done with this plugin, how do I include this in another rails application? What directories do I need to put in engines/ in addition to including the plugin in the gemfile?
In addition to this I also want some info about what the following is indicating
Additionally, the --mountable option tells the generator to mount the engine inside the dummy testing application located at test/dummy by adding the following to the dummy application's routes file at test/dummy/config/routes.rb:
mount PluginName::Engine => "/plugin_name"
What does the mount point indicate and what will be it's role once the plugin is included in a rails application?
Rails engine is an isolated rails app, that is mounted inside main app. Two main reasons to create an engine are isolation of an application part (with possible intent to split the app into pieces) and code reuse (when you use same engine in several apps)
Technically it is a ruby gem, but often engines start (and live) as an isolated part of a larger app, without being completely extracted into own repository, gem publishing etc.
For example, if you have admin part of your app, you can make it an engine:
# in gemfile:
gem 'admin', path: 'engines/admin'
# routes:
mount Admin::Engine => '/admin'
# engine's routes:
resources :foo # => because of being in an engine this will be /admin/foo
directory structure can look like:
|-app/
|-bin/
|-...
|-config/
|-application.rb
|-routes.rb
|-engines/
|-admin_engine/
|-app/
|-controllers/admin/
|- foo_controller.rb
|-config/
|-routes.rb # <- this is engine's routes
|-lib/
|-admin/
|-engine.rb
|- admin.gemspec
On our project, we have the following:
module A
# several components belong to this namespace
end
module Databuilder::A
# several components also belong to this namespace
#
When running the full test suite, in which one of the tests is like this:
describe ::A::AnotherNamespace::MyService do
# code ommited
The following error shows up:
uninitialized constant DataBuilder::A::AnotherNamespace
Unfortunately, renaming the namespace A is not an option because the components belong to a legacy monolith.
Manually requiring the file which contains :A::AnotherNamespace::MyService leads to the same error.
The files on DataBuilder:: ... live inside the /lib folder. The ones from the A namespace live inside a app/"a" folder
I'm running rspec-rails 4.0.0 / rails 5.2.4 in a ruby 2.3.0 rbenv.
No customization has been done to the autoloading.
I'm building an app which requires the frontend and the api to be separate. The folder looks like this
application/
.git/
frontend/
api/
Procfile
The API is a rails application so I'd like to use the cedar stack from Heroku.
When I try and push the application I get the message
! Push rejected, no Cedar-supported app detected
Which makes sense as it needs to look in a subfolder. How do I tell heroku to only use the sub folder?
The folder structure you posted doesn't look like a Rails app at all.
If you want to split the frontend from the api, you can perfectly to that at controller level by having two different namespaces.
That will generate a structure like the following one
app/
controllers/
api/
whatever_controller.rb
frontend/
user_controller.rb
whatever_controller.rb
public/
log/
db/
Procfile
... other standard Rails folders and files
The structure you have seems to represent two completely different Rails app. If that's the case, then you need to use two different Heroku app.
If that's not the case, then that could not work. I don't even think how you can start it, given that it doesn't represent a standard Rails structure.
I am starting to learn plugin development in rails, I was wondering what is the use of the test/dummy folder in the rails plugin environment. I understand that it has all the features of a regular app but what how does this help in the plugin environment. Furthermore I was unable to find good resources online for exploring the rails plugin development system, it would be helpful if good resources were posted.
The dummy app with /test works like fixture, to provide a basic environment to run the plugin's functional/integration tests.
Because this is a plugin(actually it's a gem), even it lives in /lib currently, it should have no dependency on your real app. But functional/integration tests need a Rails app, so here comes the dummy.
I'm trying to break several pieces of reusable application functionality into Rails engines. I have no trouble at all getting one engine to work, but the app doesn't seem to load data from subsequent engines. I'm developing multiple engines simultaneously, so I'm requiring them into my testapp's gemfile with the :path option.
Here's my (simplified) setup (my understanding of the bare minimum to setup an engine with a simple model):
my_engines/engine1/lib/engine1.rb:
module Engine1
require 'engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
end
my_engines/engine1/lib/engine.rb:
require 'engine1'
require 'rails'
module Engine1
class Engine < Rails::Engine
end
end
my_engines/engine1/app/models/engine1/model1.rb:
module Engine1
class Model1
end
end
My second Engine, engine2 is setup identically and in the same parent directory (just with the name engine2 and the model model2).
I'm using jeweler to package and generate gemspecs for both engines, and I'm requiring both engines in a test application like so:
my_engines/testapp/Gemfile:
gem 'engine1', :path => '../engine1'
gem 'engine2', :path => '../engine2'
The weird thing is that when I fire up rails console for my testapp, Engine1::Model1.new works, but Engine1::Model1.new results in "NameError: uninitialized constant Engine2::Model2". This seems to be true for all models, routes, controllers, etc. that I include into any subsequent engines. I've scoured the internet to no avail. Any thoughts?
I think I've figured this out. Just in case anyone else out there happens to be playing with Rails3 engines (much recommended), and runs into this issue (hopefully not),
the problem was having my engine.rb file and my engine_name.rb files
both sitting side-by-side in the lib dir. The solution is to create
an engine_name dir within lib and put your engine.rb file in there (I
guess Rails only loads the first engine.rb file it finds in a gem or
plugin's lib dir). So...
Bad (only loads one engine.rb in host app):
/some_engine
|-- lib
|-- some_engine.rb
|-- engine.rb
Seems to work:
/some_engine
|-- lib
|-- some_engine.rb
|-- some_engine
|-- engine.rb