I've tried installing ActiveAdmin into a rails app that already has an Admin model* and it all works, until I try to run any code (e.g. run specs, or run the rails server) which needs to access the Admin class -- then it fails as if the problem is with my Admin class:
foo/app/models/admin.rb:1:in `<top (required)>': Admin is not a class (TypeError)
from bar/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.11/lib/active_support/dependencies.rb:251:in `require'
*In my case I used --skip-users so I could reuse my Admin model, but it happens whether you do this or not. It also happens if you do:
rails generate active_admin:install Admin
How can I get ActiveAdmin to coexist with a model (or other class) called Admin
It took me a while to work this out (on a previous project I gave in and just renamed the model).
There have been some patches proposed, but actually there is a perfectly good config option that fixes this:
Edit the initializer at config/initializers/active_admin.rb so that the default_namespace is different (you could skip the default_namespace with config.default_namespace = false, but I haven't tried this).
I chose admin_ui for this:
config.default_namespace = :admin_ui
There may be more subtlety for this so you can (if you want) keep the /admin/ route rather than have admin_ui but this was good enough for me -- the official docs on this are at http://activeadmin.info/docs/1-general-configuration.html#namespaces, but don't mention this reason to change the namespace.
Related
In my app I use an engine (blogit) to which I want to add some changes / behaviours.
I followed the guides on how to override engine controllers/models and added the following:
The Code
In config/initializer/blogit.rb
# Requires extension ruby files in lib/blogit.
Dir[Rails.root.join("lib/blogit/*.rb")].each {|f| require f}
In lib/blogit/engine.rb
module Blogit
class Engine < ::Rails::Engine
isolate_namespace Blogit
config.to_prepare do
Dir.glob(Rails.root + "app/decorators/**/blogit/*_decorator*.rb").each do |c|
require_dependency(c)
end
end
end
end
In app/decorators/controllers/blogit/comments_controller_decorator.rb
Blogit::CommentsController.class_eval do
def create
Rails.logger.info "decorated controller action"
# ... overridden stripped ...
end
end
In app/decorators/models/blogit/comment_decorator.rb
Blogit::Comment.class_eval do
belongs_to :user
end
To be mentioned:
I have also created a migration to add a user reference to the comments model, since my app uses devise and I only want logged_in users to be able to comment. (Therefore I don't need the standard behaviour, so I'm going to override it.)
The Problem
If I run rake I get the weird error:
/Users/Kassi/.rvm/rubies/ruby-1.9.3-p392-railsexpress/bin/ruby -S rspec ./spec/controllers/home_controller_spec.rb ./spec/models/user_spec.rb
/Users/Kassi/demo/app/decorators/controllers/blogit/comments_controller_decorator.rb:3:in `<top (required)>': uninitialized constant Blogit::CommentsController (NameError)
However, if I run the first line that rake mentions by hand (.../ruby -S ...), all tests are being run successfully.
In my project I'm using guard with spork. Running guard will also let the tests pass without any error.
The app itself runs fine, i.e. it starts without errors and I'm able to comment as I want. My decorator action code is being executed.
So what's different when running rake?
Why does it break?
Note:
Adding require "blogit" or require "blogit/comments_controller" doesn't help. It actually can't find the controller using require.
A Demo Application
Since this problem is part of a bigger project, I created a new app from scratch for testing purposes that contains only the relevant stuff: basic rails app, rspec, devise, blogit and the decorators.
It can be found here: https://github.com/kassi/decorator_demo_rspec (git://github.com/kassi/decorator_demo_rspec.git)
Another repo using testunit (which is working!) can be found here: https://github.com/kassi/decorator_demo_testunit (git://github.com/kassi/decorator_demo_testunit.git)
Instead of performing the require statements yourself, you can try activesupport-decorators that does it for you.
I have a built a Ruby Extension for C/Objective-C and now would like to use it in a Ruby on Rails web application but everytime I try to require it, WEBrick crashes! What I have is:
I have a Ruby Class: MyRubyObject which is tied to a C class (MyExtension).
MyRubyObject has been defined with one method: myRubyMethod which is tied to a function in my C class, MyExtension: myextensionmethod which just returns a string.
myextensionmethod essentailly calls another library which performs a load of work (multiple threads and what not) but finally returns a string
after compiling everything I get a MyRubyObject.bundle file. Using IRB, I can:
require './MyRubyObject'
p = MyRubyObject.new
p.myRubyMethod
=> "Result!"
This all works absolutely fine and now I want to use it in a RoR app
I put the MyRubyObject.bundle in lib in my RoR app and then from a controller class I do a require ./lib/MyRubyObject.bundle and WEBrick crashes!!!!
Any help would be greatly appreciated!!!
Cheers
I found a solution where from here: ruby-ldap gem not work in rails3 app, but work in rails console whereby I
Put a 'require File.expand_path('../../lib/MyRubyObject', __FILE__)' in config/environment.rb file (after 'require File.expand_path('../application', __FILE__)')
Then in my controller file I just put a require 'MyRubyObject' and was then able to instantiate normally: p = MyRubyObject.new ...
So I presume this was a related issue to WEBrick loading things in an incorrect order based upon the above link but I will keep an eye on this as we'll move servers most likely and this issue may pop it's ugly head up again!
Hope this helps others!
Thanks
Moving over from django / python, I am having a little trouble getting the rails logger to log all the information I want. I am wondering how/if the following can be achieved:
Having in the log format(ter) include the specific file, function name and line where the logging statement itself was found. Essentially the equivalent of LOG_MSG_FORMAT = '%(asctime)s %(levelname)s %(filename)s:%(funcName)s(%(lineno)d) : %(message)s' in python logger?
Being able to log all requests, via something similar to a django request logging middleware. Particularly, being able to log the username (if logged in) of every request.
Am I missing something obvious? or does this require (lots of) custom code?
I just found this railtie gem that might help although I imagine it will take some "custom code" to append username to logs. See the Readme section on logging specific controllers and models.
logging-rails railtie
I don't know about getting the file, function, and line number, but it's pretty easy to log from application_controller:
class ApplicationController < ActionController::Base
before_filter :log_user
def log_user
if current_user
Rails.logger.info "Processing Request for #{current_user.name}"
end
end
end
Just to add a quick note in case this is useful for someone:
The lograge gem makes rails logs much similar to django's, plus allows very neat customization, adding parameters such as remote ip address, current_user etc.
It also reduces verbosity of rendered layouts, which I anyway found unnecessary for production. It also plays nicely with logging-rails railtie mentioned by #lukewendling.
Sadly, I still couldn't find anything that shows the file/function/line number like you can easily do with django, but I guess that's just too much to ask.
I am building a Rails application that contains Developers who have Applications. Both Developers and Applications are objects whose contents come from an external API. Thus, both of these models are hand-written and do not take advantage of ActiveModel, ActiveResource, etc.
I am trying to determine how to instantiate the Application object as an instance variable of the Developer object.
I have the following code within my Developer.initialize() function:
#apps = Array.new
data['applications'].each do |app|
#apps << Application.new(app)
end
The code is fairly self explanatory. Both developer.rb (which is where Developer is defined) and application.rb (which is where Application is defined) lie in the app/models directory. My developers controller instantiates a Developer object by calling Developer.new.
The line of code within the do block produces the following error:
uninitialized constant Developer::Application
app/models/developer.rb:24:in `initialize'
app/controllers/developers_controller.rb:11:in `new'
app/controllers/developers_controller.rb:11:in `show'
So it looks like Rails is trying to instantiate a Developer::Application, whereas I want to instantiate the Application object defined in application.rb within the app/models directory. Is there some way for this to be done?
You have to require the necessary files. In my case, from within the Developer class, I needed the following line: require 'application.rb' and everything worked fine.
I'm writing a book on Rails 3 at the moment and past-me has written in Chapter 3 or so that when a specific feature is run that a routing error is generated. Now, it's unlike me to go writing things that aren't true, so I'm pretty sure this happened once in the past.
I haven't yet been able to duplicate the scenario myself, but I'm pretty confident it's one of the forgotten settings in the environment file.
To duplicate this issue:
Generate a new rails project
important: Remove the public/index.html file
Add cucumber-rails and capybara to the "test" group in your Gemfile
run bundle install
run rails g cucumber:skeleton
Generate a new feature, call it features/creating_projects.feature
Inside this feature put:
This:
Feature: Creating projects
In order to value
As a role
I want feature
Scenario: title
Given I am on the homepage
When you run this feature using bundle exec cucumber features/creating_projects.feature it should fail with a "No route matches /" error, because you didn't define the root route. However, what I and others are seeing is that it doesn't.
Now I've set a setting in test.rb that will get this exception page to show, but I would rather Rails did a hard-raise of the exception so that it showed up in Cucumber as a failing step, like I'm pretty sure it used to, rather than a passing step.
Does anybody know what could have changed since May-ish of last year for Rails to not do this? I'm pretty confident it's some setting in config/environments/test.rb, but for the life of me I cannot figure it out.
After I investigate the Rails source code, it seems like the ActionDispatch::ShowExceptions middleware that responsible of raising exception ActionController::RoutingError is missing in the test environment. Confirmed by running rake middleware and rake middleware RAILS_ENV=test.
You can see that in https://github.com/josh/rack-mount/blob/master/lib/rack/mount/route_set.rb#L152 it's returning X-Cascade => 'pass' header, and it's ActionDispatch::ShowExceptions's responsibility to pick it up (in https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L52)
So the reason you're seeing that your test case is passing because rack-mount is returning "Not Found" text, with status 404.
I'll git blame people and get it fix for you. It's this conditional here: https://github.com/rails/rails/blob/master/railties/lib/rails/application.rb#L159. If the setting is true, the error got translated right but we got error page output. If it's false, then this middleware doesn't get loaded at all. Hold on ...
Update: To clearify the previous block, you're hitting the dead end here. If you're setting action_dispatch.show_exceptions to false, you'll not get that middleware loaded, resulted in the 404 error from rack-mount got rendered. Whereas if you're setting action_dispatch.show_exceptions to true, that middleware will got loaded but it will rescue the error and render a nice "exception" page for you.