2

I have to make a rails API only i.e. input is POST request and output will be an JSON response. I have to interact with mysql database with my own table names i.e. mysql tables are already created. Below is the folder structure with "helpers" even though we are not using any "views". We are accessing the helper methods from our controllers. Please confirm if I am correct or not. Thanks in advance.

1) app/controllers/application_controller.rb

 class ApplicationController < ActionController::API
      # Prevent CSRF attacks by raising an exception.
      # For APIs, you may want to use :null_session instead.
      protect_from_forgery with: :exception
    end

2) app/controllers/feature_management_controller.rb

class FeatureManagementController < ApplicationController

  def populate_bean


    @json = OrionCountryList.new.sample_function
  end

  def send_response(bean)
    helper = FeatureManagementHelper.new
    if (bean.method.eql?"get_feature_list") && (!bean.app_key.blank?) && (bean.app_key!=nil) && (bean.app_key.casecmp("NULL")!=0)
      logger.info bean.print_bean "Request for fetching featureList by app_key : " + bean.app_key.to_s + " And userID: " + bean.user_id.to_s
    @@json_response = helper.get_feature_list bean

    else
      logger.error "METHOD NOT FOUND. method during feature management :"+bean.method+" app_key :"+bean.app_key
      @@json_response = {:message => "API not avaliable"}
    end
    logger.info("Final json_response sent to app : "+@@json_response.to_json)
    render :json => @@json_response
  end
end

3) app/helpers/application_helper.rb

class ApplicationHelper 
    APP_CONFIG = YAML.load(File.read(File.expand_path('../../../config/app_config.yml', __FILE__)))
end

4) app/helpers/feature/feature_management_helper.rb

class FeatureManagementHelper 

  def get_feature_list(bean)
    response = Hash.new
    response = {:success_code => "1"}
    return response
  end

end

Here we are using "class" key word inside the helpers. But on searching, it seems "module" key word is needed. But we couldn't find the way to access module methods of helpers inside controllers.

Any help is appreciated.Thanks!!!

UPDATE

@Ekkerhard, Thanks for the suggestion, I have refrained from using helpers in the above way mentioned and instead used PORO for implementing my business logic as suggested by @spikermann using this_link

Upon implementing the changes, my code structure looks something like this:

1) app/controllers/feature_management_controller/feature_management.rb

class FeatureManagementController
  class FeatureManagement
    def get_feature_list(bean)
      response = Hash.new
      response = {:success_code => "1"}
      return response
    end
  end
end

Similarly for any controller "test_controller" I have a folder named "test_controller" at the location /app/controllers/ and I am keeping the business logic inside a test.rb file inside this "test_controller" folder.

2) We have all the controllers inside the /app/controllers

3) We have all the models inside the /app/models

4) We are reading the configuration file inside /config/application.rb

 class Application < Rails::Application
    config.autoload_paths += Dir["#{config.root}/lib/**/"]
    APP_CONFIG = YAML.load(File.read(File.expand_path('app_config.yml', __FILE__)))
    config.time_zone = "New Delhi"
    config.active_record.default_timezone = :local
    config.autoload_paths += Dir["#{config.root}/app/**/"]
 end

Though if I read the config file from the feature_management.rb file things are working just fine i.e. adding this line to the feature_management.rb file :

/app/controllers/feature_management_controller/feature_management.rb

APP_CONFIG = YAML.load(File.read(File.expand_path('../../../../config/app_config.yml',
__FILE__)))

but upon trying to read the configuration from the application.rb file I am getting an error :

NameError (uninitialized constant FeatureManagementController::FeatureManagement::APP_CONFIG):

I was wondering whether this is the correct way to proceed and is there a better way to do it.

Appreciate your inputs..!!!

Rachit
  • 51
  • 6
  • It seems like your helpers aren't helpers by Rails' conventions. They are just PORO that can live in the `app/models` (or `lib`) folder. – spickermann Jan 14 '16 at 06:56
  • hey @spickermann, I have implemented PORO and have updated my question, can you help me out here. – Rachit Jan 14 '16 at 11:01

2 Answers2

0

If you need, you can include the module inside your controller and access the methods. Like:

include HelperModuleName
Babar Al-Amin
  • 3,939
  • 1
  • 16
  • 20
  • upon doing so, I am not being able to use the methods inside the helpers. The error that I am getting is "NoMethodError (undefined method `get_feature_list ' for FeatureManagementHelper". I have tried accessing the method this way : HelperModuleName.HelperModuleMethod – Rachit Jan 14 '16 at 06:59
  • After including the module, you can directly call `get_feature_list` method. You won't have to prepend it with your module name. – Babar Al-Amin Jan 14 '16 at 07:14
0

Frankly, to me it seems that you are trying to just "get by" with Rails here and are using other paradigms in a Rails environment. I don't think you're going to be happy with that in the long (or even short) term; if you use Rails that way it will just get in your way.

First of all, I would not use helpers in this way, at all, ever. In my opinion, helpers are there solely for cutting out "stupid" code from view templates, to cut down on "programming" clutter inside otherwise HTML'ish/JSON'ish templates. And they are definitely never domain methods. They do domain-agnostic stuff like render form elements, complex tables or things like that.

Just because you are not outputting HTML but JSON does not mean you have to ditch the MVC paradigm completely, like you are doing. There are JSON templates, see In Rails, how do you render JSON using a view? .

You are using a helper to load configuration. Configuration lives in config/application.rb, config/environments/*.rb, config/initializers/*.rb etc. - see http://guides.rubyonrails.org/configuring.html . You should never need to load the YAML in a helper.

Your controller code suggests that you do not use routes.rb to structure your requests. Branching like you have in your controller is a big smell for me. See http://guides.rubyonrails.org/routing.html .

Maybe not the answers you are looking for, but that's my 2€. :)

Community
  • 1
  • 1
AnoE
  • 8,048
  • 1
  • 21
  • 36
  • hey, really appreciate your help. I have updated the question following your links. Just wanted to know whether this is the correct approach. – Rachit Jan 14 '16 at 09:47
  • Looks like you're on track. :) There is little that absoutely must be done "just so" in Rails, but you tend to be more likely to actually benefit from it if you respect their basic designs/file layouts. – AnoE Jan 14 '16 at 19:46