I have a method like this in rails app:
def current_user
return #current_user if #current_user.present?
#current_user = current_user_session && current_user_session.record
end
I haven't used the .present? method before so I went into my interactive ruby shell to play around with it.
Whenever I use xxx.present? it returns a NoMethodError. It doesn't matter if xxx is a string, number, array anything.
How can I use this method?
present is a method provided by ActiveSupport. It is not a part of core ruby. That is why you are not able to use it in the ruby shell. To play around with it, you will need to require the relevant libraries in your console (e.g. irb / pry):
require 'active_support'
require 'active_support/core_ext'
This way, you will have access to all the utility methods provided by activesupport.
present is a rails method, not ruby.
try using rails c instead of irb to use it in your console.
As mentioned above, .present is not in the ruby standard library. Instead, it's in active_support (docs.)
To use active_support, first install the gem, then require it in irb or your ruby script. More information on how to selectively load activesupport extensions can be found in the Rails guides.
Related
Is it possible to access Pry's show-source method from within a Ruby file? If so, how is this done?
For example, if I had this file:
# testing.rb
require 'pry'
def testing
puts 'hi'
end
puts show-source testing
And ran ruby testing.rb, I'd like the output:
Owner: testing.rb
Visibility: public
Number of lines: 3
def testing
puts 'hi'
end
To explain the rationale for this, I have a test stubbing a method, though the original seems to be getting called on occassion and I thought it would be handy to output the source of the call to see where it's coming from. I know there are simpler ways of doing this, though started down this rabbit hole and am interested in seeing whether this can be done :)
Running the slightly head-twisting show-source show-source shows a few methods within the Pry::Command::ShowSource class, which inherits from Pry::Command::ShowInfo.
Pry::Command::ShowSource shows three methods: options, process and content_for, though I've not been able to successfully call any.
My best assumption is the content_for method handles this, working with a code object assigned from the parent class (i.e. Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super])), though I've not been able to crack this.
Anyone have any ideas or examples of doing this?
Ruby has the build-in method Method#source_location which can be used to find the location of the source. The method_source gem builds upon this by extracting the source based upon the source location. However this doesn't work for methods defined in the interactive console. Methods must be defined in a file.
Here is an example:
require 'set'
require 'method_source'
puts Set.method(:[]).source_location
# /home/user/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/set.rb
# 74
#=> nil
puts Set.method(:[]).source
# def self.[](*ary)
# new(ary)
# end
#=> nil
Keep in mind that all core Ruby methods are written in C and return nil as source location. 1.method(:+).source_location #=> nil The standard library is written in Ruby itself. Therefore the example above works for Set methods.
You can access source of a method without using pry with a Object#method and Method#source_location as described in this answer: https://stackoverflow.com/a/46966145/580346
I am trying to write a Ruby Gem which, when required, adds a function to the global scope.
I have followed the ideas here:
How can I add a method to the global scope in Ruby?, however, it just doesn't work! (on Ruby 2.4.3 anyway)
Here is my actual source code, but the below also summarises what I've done and what isn't working:
# example.rb
module Example
def self.hello()
puts "Hello"
end
end
extend Example
Then
# app.rb
require 'example' # Having built as a gem
hello() #=> `<main>': undefined method `hello' for main:Object (NoMethodError)
Where did I go wrong?
Sergio solved this for me, though I don't quite understand how!
It was considered good practice to encapsulate the methods in a module, so that users of the gem can use them directly (hello) or scoped (Example::hello) as they pleased.
By removing self. the method can be accessed directly only. By including self. it doesn't work at all. However, by doing:
module Example
extend self
def hello
puts "Hello"
end
end
extend Example
...it does work in both ways.
I would like to use the distance_of_time_in_words method in the date_helper.rb Rails file (see on Github) in an non-Rails Ruby project.
How can I include it? It requires other files, so how to include them?
I don't want to include all of Rails because that would slow down the development process.
Ruby 1.9.3
This method, distance_of_time_in_words is in actionpack/lib/action_view/helpers/date_helper.rb. So you should require 'action_view' and action_view/helpers to load this method. And the method is defined in module ActionView::Helpers::DateHelper, you can include it in your class. The method is an instance method.
require 'action_view'
require 'action_view/helpers'
class Klass
include ActionView::Helpers::DateHelper
end
c = Klass.new
c.distance_of_time_in_words( ...... )
If this is the only thing you want from it, then I'd just go take the source code and hack it to remove the dependencies (which appears to just be some I18n translations. To support the hack, you can probably translate this test suite.
Why would I do this instead of using the gem? Because it's just such an enormous dependency. It's so enormous that you actually notice it loading all that code. I'd rather rip out the method and hack it to work than depend on all of that (again, assuming this is the only thing you want from the lib).
Does to_json require parameters? what about within rails?
I started getting the error "wrong number of arguments (0 for 1)" when doing myhash.to_json
Unfortunately I'm not sure when this error started happening, but I guess it relates to some versions of either rails or the json gem. I suppose my code (in a rails controller) is using the ActiveSupport::JSON version of to_json, rather than the to_josn method supported by the json gem. ActiveSupport::JSON vs JSON
In environment.rb I have
RAILS_GEM_VERSION = '2.3.2'
and also
config.gem "json", :version=> '1.1.7'
It's just a simple hash structure containing primitives which I want to convert in my controller, and it was working, but now I can't seem to run to_json without passing parameters.
Do you have your own version of to_json defined in a model that doesn't take args? If so, make it accept *args or opts = {}
If ActiveSupport in that version of rails has to_json, why use a gem? The Gem probably redefines Object#to_json to require arguments and thats why you are getting an error.
Look in the code of the json Gem and find where to_json is defined to verify this.
to_json does not require parameters, when you're using the version provided within rails (ActiveSupport::JSON) So that error message shows that it must be trying to call the to_josn method defined in the json gem.
So my actual source of confusion was around the way rails loads these libraries.
It will load the json gem and use it within a controller, even if I don't have a line saying 'require json' because rails loads gems as defined in environment.rb, so in fact I needed to remove the line
config.gem "json", :version=> '1.1.7'
...from my environment.rb . My code had been broken since I had added that. Confusingly I do need that gem, but only for scripting I'm doing outside of rails.
I'm really tired of typing my_ar_object.errors.full_messages in my console when i'm testing things...
So, I want to define this:
module ActiveRecord
class Base
def err
errors.full_messages
end
end
end
in my ~/.irbrc so that it is exclusive to script/console.
I don't want to define it in some rails initializer since I don't believe it belongs in the rails project (this is a irb helper)
The problem is, when I do that, this happens:
/.../gems/rails-2.3.5/lib/initializer.rb:437:in `initialize_database':NoMethodError: undefined method `configurations=' for ActiveRecord::Base:Class
Any ideas how I might make this work?
Did you load ActiveRecord in your .irbrc before defining the err method? Try adding
require 'active_record'
or
require 'rubygems'
gem 'activerecord', '2.3.5' # or whatever version you use
before defining the err method.
And another hint: irb looks for an .irbrc file in the current directory and in your home dir. So you could also craft a project-specific .irbrc in your project root directory. This way, you don't have to introduce ActiveRecord to your default irb config since it is a rather hefty dependency.