So I'm upgrading a Rails 2 app to Rails 3.2, which is mostly going smooth. However, I have a controller that handles uploading import files, ImportsController, and it uses some actions from a module Importable that provides the same actions to another controller.
class ImportsController
# standard REST stuff
include Importable
end
module Importable
def status
# code to return json has of state machine status
end
end
# routes
resources :imports do
member do
get :status
end
end
Which blows up with: The action 'status' could not be found for ImportsController. If I were to say, copy the status action into the ImportsController, everything is fine, however then I'd have to do the same thing in the second controller, so boo duplication. Any ideas what could be causing this?
It was a red herring. With the introduction Rails introduced ActionController::Metal, which defines def status
So I believe it's blowing up because Rails is now trying to use my method to get the HTTP status code and blowing up because it's not returning something that makes sense. Will refactor.
Related
I am trying to define some helper methods to be used in the app's controller, but it seems that rails don't even call the controller. just for the test I have the following controller in my app/controllers/my_engine/application_controller.rb and as the documents say rails should find it first and an error should raise because THIS_SHOULD_PRODUCE_ERROR is unknown, but the rspec happily executing without any errors!
class ApplicationController < ActionController::Base
THIS_SHOULD_PRODUCE_ERROR
end
I even tried to mimic the devise's way but the results are the same!
The guide section on the app directory suggests that the application_controller in an engine "will provide any common functionality for the controllers of the engine".
So I wouldn't expect that any additions to that controller will be available to all controllers in an application.
That also means that your application_controller is, I suspect, not getting called when you're running your test. Which would explain why you're not seeing an error.
In terms of how devise does it I think you need to be looking at how define_helpers works. The code you've linked to in your question is the application controller in the test app for the devise gem.
I noticed that I have got things wrong, and the application_controller in the engine does not get applied to application_controller in the app! Also, I couldn't figure out how the devise did it, but I have come up with the simple workaround for this:
require_relative 'controllers/helpers'
module Acu
module Injectors
class << self
ActiveSupport::Notifications.subscribe "start_processing.action_controller" do |**args|
eval((Acu::Configs.get :base_controller).to_s).class_eval do
include Acu::Controllers::Helpers
end
end
end
end
end
This will inject controller helpers to the user's base controller (which I get from the user, default: :ApplicationController) at the end of the class, which is perfect for me (but don't know how to add it to begging of the class if anyone needs it)
I have been developing in Ruby on Rails for a while now so I am completely confused at why this is happening. I created a controller called ApiController as you can see below.
class ApiController < ActionController::Metal
def documentation
end
def request_manager
end
end
Here are the routes I set to setup the documentation view.
Rails.application.routes.draw do
root 'landing#home'
get 'api' => 'api#documentation'
end
There is an documentation.html.erb file in the api folder as well, but
No matter what I do I get the following error.
It makes no sense to me why it's not routing correctly and has me completely baffled.
As a side note, the landing controller works perfectly fine and routes to the home page with no problem so it's just this controller.
Actually I just figured it out. Turns out that ActionController::Metal turns off must functionality including rendering so when you attempt to make it render as a normal controller, it faults while loading and the error is somewhere in the class files of Ruby's main code. Hence me not being able to find what was going wrong exactly till I looked up more documentation for the Metal controller.
I was using ActionController::Metal for it's speed and just didn't realize how much it stripped away from functionality in the process.
I have started with this example, I managed to make everything work on sinatra.
But I want to use this in my Rails app so I did the followings:
Create the client, in sinatra they do that in the configure block.
In rails I did:
In the config/initializers file I've added the entire block which is in sinatra after that I wrote a class GoogleCalendar::Base where I have:
class GoogleCalendar::Base
class << self
attr_accessor :api_client, :calendar_api
end
def self.configure
yield self if block_given?
end
So like this I replaced the set :api_client, client, set :calendar, calendar
In my application controller then I've added the:
def user_credentials
...
(what i've changed was instead of session i've added `see below`)
auth.update_token!(access_token: session[:access_token],
refresh_token: session[:refresh_token])
end
Because I wasn't working if passing session maybe someone can tell me why? (conflict between sessions? and it was working with cookies.)
Also I have created other functions in the application controller which I use for callback and get content.
def api_client
GoogleCalendar::Base.api_client
end
def calendar
GoogleCalendar::Base.calendar_api
end
In the end I've created the rest of the controllers/views and everything works fine.
My final question is: It is ok creating the Google::APIClient in the initialisers folder because I've notice that every time I change something in my controllers the code brakes, but if I restart the server everything works ok.
I am testing http/https content for images that are on a web application running Rails 2.3. The layout is basic. I have my controllers with accompanying test directories including functional and integration folders with tests.
I'm still relatively new to Rails but I was wondering if there was a way to create a file that can test attachments across different controllers. For example, I need to test if whether the images on this web app are either http or https on the About/Projects/People/Accounts/ and Explore controllers. Instead of opening each of the about_controller_test, project_controller_test, etc. files writing the lines of code, I wanted to know if there was a way that I can make a master file that includes all of the controllers.
What I would like to do is to create some sort of module that I can include/extend the controllers in. This makes sense in my head but I run into the problem with naming conventions. If I wanted to make an attachments_test.rb, I wouldn't be able to do this because I don't have an attachments_controller.rb file that maps to it. How can I work around this?
All I would like is to make a file named along the lines of testing_attachment_protocols_test.rb which doesn't map to any controller but where I can put my tests in. I want to have one file to write my tests for different controllers instead of writing 1 test in several files. Would this file be included into test_helper.rb? Any help would be appreciated. Thanks.
---------EDIT-----------------------
I figured out the structure that I basically would like to implement for the test. Below is the general structure of the test that I would like to do.
require File.dirname(__FILE__) + '/../test_helper'
require 'open-uri'
def controller
......
end
class controller; def rescue_action(e) raise e end: end
class controller < Test::Unit::TestCase
def setup
#controller = controller
#request = ActionController::TestRequest.new
#response = ActionController::TestResponse.new
end
test "attachments url pattern for home page should include http when not logged in" do
setup
get :home
assert not_logged_in
#puts #response.body
assert_select("a img", :url =~ /sw.amazonaws/) do |anchor|
assert_equal 'http', anchor.protocol
end
end
end
Now the thing that I have trouble now is what to put in the method call for controller. My goal is to try to be as dynamic as possible. My goal is pretty much to create an attribute accessor method for different Controllers. Any thoughts?
I'm trying to override an action in a controller defined by a Rails Engine.
It seems like I need to require the original file before reopening the class, like so:
require File.join(RAILS_ROOT, 'vendor/plugins/myplugin/app/controllers/some_controller')
class SomeController
def index
render :text => 'this is my index'
end
end
This makes sense, but that require is pretty ugly. Is there some sort of Rails magic that would allow me to avoid the initial require?
This is a complete guess...
Seems more of a load timing problem. As in, your file is getting loaded before the plug-in. Where is your action located? config/initializers? lib?
I'm not to sure when Rails Engines gets loaded so play around with the location (should work by putting it in lib).
Or, better yet, create your own plug-in with the changes and make sure it loads after the original.
And you probably want something more like:
SomeController.class_eval do
def index
...
end
end