Call a rails method from a class outside of MVC pattern - ruby-on-rails

I'm creating a news feed application that consumes an XML feed for later use.
I am struggling to get the app to call a method I have written inside of a class outside of the default Rails folders. How can I load this class into the app for use in a controller (for example)? I've read a bunch of questions on SO, resulting in the following structure / code.
My understanding is that with the following I shouldn't need to require 'fetch_feed.rb' from the controller or place anything in the lib folder. I am however getting the following error:
NoMethodError (undefined method `fetch_news' for FetchFeed:Class):
app/controllers/v1/news_items_controller.rb:18:in `index'
I am trying to call a method from the FetchFeed class
Folder Structure
- app
- controllers
- retrievers
- fetch_feed.rb
fetch_feed.rb
class FetchFeed
def fetch_news
// Code here
end
end
aplication.rb
module FeedReaderApi
class Application < Rails::Application
config.autoload_paths += %W(#{Rails.root}/app/retrievers)
// Other code
end
end
news_item_controller.rb
class V1::NewsItemsController < ApplicationController
def index
FetchFeed.fetch_news
end
end
Any help much appreciated.

Should be:
FetchFeed.new.fetch_news
fetch_news has been defined as an instance method. So you need an instance of FetchFeed to call the fetch_news method.
To make FetchFeed.fetch_news work, define it as a class method like below:
class FetchFeed
def self.fetch_news
// Code here
end
end
OR
class FetchFeed
class << self
def fetch_news
// Code here
end
end
end

Related

Call a method from an another class in Ruby (API rails)?

The question can be stupid, but I always develop in C# and now I need to develop in Ruby.
And I don't really understand how to call a method from an another class.
I mean, I've this structure :
- model
|_________ my_model.rb
|_________ helper
|____ my_helper_class
my_model.rb
def self.create_new_ticket(member_to_update)
# I want to call here my_helper_class
MyHelperClass.generate_guid
end
my_helper_class :
class MyHelperClass
def generate_guid
return "So haaard"
end
end
And I don't have access to my method named generate_guid from my other class.
I've this type of error :
uninitialized constant
I would like to have an access with a static class or whatever. The initilize method doesn't work too (given argument problem ??)
So I think I understand bad something with Ruby and the manipulation of objects because of my habits in C#.
Can you help me please ? With some good documentations or an example here ?
Thanks a lot guys.
I think your error is straightforward. Your generate_guid is not a "static method" or "class method". You have to put self in front of it in the definition which will make it a class method.
Another important thing to notice is you have created /helper folder inside /model so you have to implement helper class inside a module named Helper which should be same as folder name.
Helper class should be
module Helper
class MyHelperClass
def self.generate_guid
return "So haaard"
end
end
end
An alternate way to define class methods would be:
module Helper
class MyHelperClass
class << self
def generate_guid
"So haaard"
end
def some_other_class_method
"some thing"
end
end
end
end
So, whenever you have to call static method you have to call it with full scope like Helper::MyHelperClass.generate_guid

Using methods defined in a module with class methods in Ruby

I have a small problem that I can't quite get my head around. Since I want to reuse a lot of the methods defined in my Class i decided to put them into an Helper, which I can easily include whenever needed. The basic Class looks like this:
class MyClass
include Helper::MyHelper
def self.do_something input
helper_method(input)
end
end
And here is the Helper:
module Helper
module MyHelper
def helper_method input
input.titleize
end
end
end
Right now I can't call "helper_method" from my Class because of what I think is a scope issue? What am I doing wrong?
I guess that is because self pointer inside of do_something input is InternshipInputFormatter, and not the instance of InternshipInputFormatter. so proper alias to call helper_method(input) will be self.helper_method(input), however you have included the Helper::MyHelper into the InternshipInputFormatter class as an instance methods, not a singleton, so try to extend the class with the instance methods of the module as the signelton methods for the class:
class InternshipInputFormatter
extend Helper::MyHelper
def self.do_something input
helper_method(input)
end
end
InternshipInputFormatter.do_something 1
# NoMethodError: undefined method `titleize' for 1:Fixnum
As you can see, the call has stopped the execution inside the helper_method. Please refer to the document to see the detailed difference between include, and extend.

Including reopened class inside controller

I want to add custom methods to the Recurly::Account class by reopening it, and then use it in my controller.
something like this:
#reopen class
class Recurly::Account
#my custom method
def my_meth_1
end
end
class MyController
def index
account = Recurly::Account.find( ... ) #gem method
account.my_meth_1 #my custom method
end
end
In which file should I reopen the Recurly::Account class and how should it be included in my controller?
I think lib folder is a good place for this.
Simply create a file like this
# lib/recurly.rb
class Recurly::Account
def my_meth_1
end
end
how should it be included in my controller?
You will probably need to turn on autoloading from lib, see this topic how to do it Rails 3 autoload. After that, you can call it directly from controller.

Display a Variable from a Method in a File in the /lib/ directory on a View in Rails

In a file called foo.rb in my /lib/ directory it reads:
module Foo
def some_method
#text_1 = "Hello!"
end
end
How can I get the results of this method to show up in a View?
I've seen that I need to include the following line in the /config/application.rb file:
config.autoload_paths += %W(#{config.root}/lib
However, I do not completely understand how to pass a variable from a module in a file saved in the /lib/ directory - to show up in a View. I appreciate any advice.
In order to get that value to show up in the view, you'll need to understand how modules are used in Ruby. Typically modules are mixed into other classes either by including or extending them. This would then make that method available to another class which could then be referenced in the view. In your case you might want to include it so it becomes available to instances of whatever class you put it in. Say you have an ActiveRecord model called MyClass and you include Foo. You can then call my_method on instances of that model as demonstrated below:
class MyClass < ActiveRecord::Base
include Foo
end
In your controller:
class MyController
def new
#my_class = MyClass.new
end
end
In your view:
#my_class.some_method
Having said all that, it seems like there might be a better way to do whatever it is you're trying to do :)
Yes.I agree with
Beerlington.
You can do it in an other way,
It is not mandatory to add config.autoload_paths += %W(#{config.root}/lib to application file.Because by default the files which are located in /lib directory won't be executed at first when we run an application using rails s.
In order to make those files to be loaded,we need to include that line in application.rb.
Otherwise,we can directly write it as below,
In model,
require 'Filename'
class MyClass < ActiveRecord::Base
include Foo
end
In controller,
require 'foobar'
class BuyerController < ApplicationController
include Foobar
end
In foobar.rb,
module Foobar
def Foobar.foobar
"Hello world!"
end
end
In view,
<%= Foobar.foobar %> (You can directly call the method by using Modulenmae.Methodname)

Extend instance method of model

I'm trying to extend a specific model in my app using railtie. Adding class methods works, but neither does instance methods. I have the following code:
class Railtie
def self.insert
return unless defined?(::ActiveRecord)
::MyApp::MyModel.extend(ModelMethods)
end
end
module ModelMethods
def hello
puts "hello"
end
end
Now, I'm able to call MyModel.hello. But what should I do if i want to add some instance methods? When I try to add them through ::MyApp::MyModel.include(InstanceMethods) it fails with something saying calling a private methods.
include is a private method and cannot have an explicit receiver. You can get around this limitation by using send:
MyModel.send(:include, InstanceMethods)

Resources