get Rails3 app name in a template that generates a rails app? - templates

I have a template that generates a rails app. The problem is that in my template scenario I substitute some files, like environment.rb, that need to know rails app name to run things like AppName::Application.initialize!. I could get the app name from the command line arguments, but that's not always possible, since a user could do that: rails new ./ and the app name would be the name of the current dir then, but I would get nothing from the argument list.
So I'd like to know a certain way of getting a Rails app name in a template scenario.

What you're looking for is the app_name attribute (as George Yacoub suggests).

You can use app_name inside your generator file.
Lots of documentations here
http://api.rubyonrails.org/v3.2.14/classes/Rails/Generators/AppGenerator.html#method-i-app_name
and it changed to application_name in rails 4
http://api.rubyonrails.org/classes/Rails/Generators/NamedBase.html#method-i-application_name

Related

Separate by apps in drf-spectacular

Here it is the UI i can get from drf-spectacular redoc:
screenshot
As you can see the only way to know the apps is from the names:
v1_foo_foodcourtrests_des
v1_ord_customer_basket_li
Here foo and ord are app names.
But I want to have a separator or something to separate these by the app names
Here is what I got so far and still no luck:
https://drf-spectacular.readthedocs.io/en/latest/settings.html#settings

Why does a Rails engine's gem name have to "match" the module/namespace name?

I am building my first Rails engine. I called it my_engine, so it generates the files
lib/my_engine.rb
lib/my_engine/engine.rb
lib/my_engine/version.rb
That all have the module named MyEngine. And in the gemspec, the gem name is also set to my_engine.
If I create a model my_model, it goes into app/models/my_engine/my_model.rb, and is generated as
module MyEngine
class MyModel < ActiveRecord::Base
end
end
If I make a class method in here, and put the gem in a Rails project, it all works fine.
def self.hello
"Hello from your Engine's model!"
end
$ bundle exec rails c
[1] (pry) main: 0> MyEngine::MyModel.hello
=> "Hello from your Engine's model!"
However, I do not want the gem name to be my_engine. But if I change the name in the gemspec to something else, like what-i-really-want-to-name-it, everything stops working. Rails cannot see my model, although it can see my namespace. I am indeed changing the gem name in the Rails app and re-bundling, so it's not an issue of that.
$ bundle exec rails c
[1] (pry) main: 0> MyEngine::VERSION
=> "0.0.1" # default version from engine generation
[2] (pry) main: 0> MyEngine::MyModel.hello
NameError: uninitialized constant MyEngine::MyModel
from (pry):2:in `__pry__'
Why is "this" tied directly to the gem name? Is there any kind of workaround for this? I would really like to have the gem name and the module name to be different values.
Using: Rails 4.2.6, Ruby 2.3.0
The answer is that one of Rails' foundational concepts is:
Convention over configuration.
When you decide to override the principle of Convention with Configuration, that's a Rails anti-pattern. Is it possible to to do it and be happy and have a working Rails app? Sure, but it's not code you would want to show as an example of your work on a Rails app.
So, the convention is that the module name matches the gem name. It's just a convention, but since convention is the mutually agreed law in Rails town, you're going anti-pattern when you don't follow it.
Added in response to OP comment
Rails engines are typified by the fact they use an isolated namespace and isolated resources. Gems don't, so in effect, the answer is yes, using a Rails engine does enforce a namespace convention that does not exist for a gem. And that namespacing is used by the middleware to keep the main_app separated from the engine at runtime. Two examples to illustrate:
An extreme example: you can have an app mounted as as engine on itself. Namespacing isolates one from the other so the middleware services act on the right processes which are only differentiated by the namespace.
Another example: 2 engines mounted on a main_app. Now there are essentially 3 apps running. How would you want to implement non-conventional namespace isolation in this case?
So...
It is possible to hammer in a nonconforming namespace in a Rails engine? Probably. I've never tried. But your engine will not be portable. And worse, someone installing it will not be able to mount another engine that is conforming (and sharing the main_app and the middleware stack) because you've forced them into a configuration maze that breaks a conventional Rails engine. This last part is a theory.

How to use Rails 4.1 to preview e-mails defined inside a mountable engine

We have SomeMailer set up inside our engine. Upon generation of the mailer, Rails creates an SomeMailerPreview class, with the comment:
# Preview this email at http://localhost:3000/rails/mailers/some_mailer/test
However, once I run the Dummy app inside my engine, that URL doesn't resolve.
The engine is mounted on the root path '/':
mount MyEngine::Engine => "/"
I've tried different combinations of the url with the engine name in there, but doesn't resolve.
Is it possible to use the preview feature for a mailer inside an engine?
A little late on this but figured I would answer anyway. You can get your previews recognized by letting rails know where the previews path is. By default, it looks in
"#{Rails.root}/test/mailers"
and so your mailer previews have to be there for the url to resolve correctly. But you can change this by setting the path yourself in the development.rb file of Dummy
config.action_mailer.preview_path = "#{YourEngineRoot}/test/mailers"
And placing your previews in the path given. Your Url should resolve correctly after that.
I have the same issue. Luckily in my case, my engine is directly reliant on the main application. In the main application, I have my mailer previews even though the mailer is within my engine.
class ApplicantMailerPreview < ActionMailer::Preview
# Accessible from http://localhost:3000/rails/mailers/applicant_mailer/applicant_email
def applicant_email
recipient = MyEngine::ApplicantEmail.all.first
applicant = recipient.applicant
job = applicant.job
MyEngine::ApplicantMailer.applicant_email(job.id, applicant.id, recipient.id)
end
end

Rails console: Unable to autoload constant

I have a Customer_ratings model that allows users to leave feedback on each other. The web app is working properly, and feedback is collected, stored and displayed.
I wanted to go in and delete some feedback through the rails console, but when I enter Customer_rating.all, I get the following error:
LoadError: Unable to autoload constant Customer_rating, expected /Users/myapps/app/models/customer_rating.rb to define it
Similarly, if I enter Customer_rating[0], I get:
RuntimeError: Circular dependency detected while autoloading constant Customer_rating
I don't have this issue while accessing other tables through my console.
What could be causing the issue, and why wouldn't this error prohibit Customer_ratings from working properly through the web app?
It seems like a case of messed up naming convention.
As per Rails naming convention, file names should be in snake_case and class names in CamelCase. In your scenario, the file name should be customer_rating.rb and class name should be CustomerRating.
After making these changes, use CustomerRating.all(as the updated class name is CustomerRating) to fetch all the customer ratings. Do not use Customer_rating.all.
I'd also like to add a scenario of this problem that I found for future reference.
I'm running Rails 4.0 and I had this same problem but what happened was I had a model named Student inside student.rb that was contained in a folder called Student. I didn't realize it at first but the folder name was the problem. Changing the folder name to something other than a model name solved the problem.
If the naming convention is not off, like in this question, it may be an issue on initial first load if you're making a lot of requests at the same time. I experienced this with nested controllers Api::LocationsController.
I solved it by enabled eager_load in development env:
Rails.application.configure do
...
# Enabled this to avoid crash unable to autoload controller
# Error happens when you start and stop server on initial requests
# solution found via https://github.com/rails/rails/issues/32082#issuecomment-367715194
config.eager_load = true
I based this off of rails issues comments: https://github.com/rails/rails/issues/32082#issuecomment-367715194
You just need to modify the name of the Module
For example if the link is http://sairam.esy.es/users/customer_rating then
you controller should like be
module Users
class RatingController
# ...
def customer_rating
# ...
end
# ...
end
end

Invoking django tests in subdirectories

I recently split up an app into subdirectories. For example, I had a "shop" app, and I split it up into shop/foo, shop/bar, shop/baz subdirectories, treating each one as a separate app, so my INSTALLED_APPS now looks like:
"shop",
"shop.foo",
"shop.bar",
"shop.baz",
...
I want to be able to run the tests in shop/foo/tests.py by doing:
python manage.py test shop.foo
However, if I do that, I get the error:
ValueError: Test label 'shop.foo' does not refer to a test
On the other hand, I can run the tests by doing this:
python manage.py test foo
Why is this happening, and what can I change so that I can run the tests as "shop.foo" instead of "foo"?
This is because Django expects the arguments to test command to be of the format:
app_label[.TestCase[.test_method]]
There is no way of doing this with the stock test runner (see, Carl Meyers comment). If everything goes well, this should be fixed in Django 1.5, but in the meantime you can use an alternate runner which accepts full module paths: django-discovery-runner.
django-discover-runner has been made part of Django 1.6.. :)
For Version <1.6 , it can be used as a third party app.