How to find out where a function is overridden? - ruby-on-rails

In my Rails project, I saw the link_to is overridden in config/initializers/extend_action_view.rb
module ActionView
module Helpers
def link_to(name, options = {}, html_options = nil)
...
end
end
end
I found that with the famous command line in linux grep -r 'def link_to' *.
My question is : Is there a way to find out it in rails console ? Is there a native function rails or ruby can give us the path of file ? Something like .ancestors for a object.
ps: My IDE is vi

If you use the pry gem, you can find it by using Method#source_location.
Pass binding.pry in your view and render it. Then write:
method(:link_to).source_location
=> ["path_to_helper.rb", 124]

Use $ command in pry gem
Insert binding.pry in your code, which sets a breakpoint and then in the Pry commandline use the $ command
[1] pry(#<AdminController>)> $ Person.find
From: /Users/joe_example/.rvm/gems/ruby-1.9.3-p551/gems/composite_primary_keys-8.1.0/lib/composite_primary_keys/core.rb # line 21:
Owner: ActiveRecord::Core::ClassMethods
Visibility: public
Number of lines: 38
def find(*ids) # :nodoc:
# We don't have cache keys for this stuff yet
return super unless ids.length == 1
...
The $ command is literally worth dollars. It shows you where a method is defined as well as the source code.

Related

Ruby: parametrize string without Ruby on rails framework (Jekyll plugin)

I have plugin that takes attribute from post's front matter and uses it in permalink. Problem is I need to clean up any accents and diacritics from the string before putting it in to the permalink. Ruby on rails has method called parametrize which does exactly what I need but I have no idea how to use it in plugin.
This is plugins code I have:
module JekyllCustomPermalink
class CustomPermalink < Jekyll::Generator
safe true
priority :low
def generate(site)
# nothing to do, wait for hook
end
Jekyll::Hooks.register :documents, :pre_render do |doc|
begin
# check if jekyll can resolve the url template
doc.url
rescue NoMethodError => error
begin
if !doc.collection.metadata.fetch("custom_permalink_placeholders").is_a?(Array)
raise CustomPermalinkSetupError, "The custom placeholders need to be an array! Check the settings of your '#{doc.collection.label}' collection."
end
def doc.url_template
#custom_url_template ||= collection.metadata.fetch("custom_permalink_placeholders").inject(collection.url_template){|o,m| o.sub ":" + m, data[m].to_s.parameterize}
end
rescue KeyError
# "custom_permalink_placeholders"
raise CustomPermalinkSetupError, "No custom placeholders defined for the '#{doc.collection.label}' collection. Define an array of placeholders under the key 'custom_permalink_placeholders'. \nCaused by: " + error.to_s
end
end
end
end
end
but I get this error:
john#arch-thinkpad ~/P/blog (master)> bundle exec jekyll serve --trace
Configuration file: /home/john/Projects/lyricall/_config.yml
Source: /home/john/Projects/lyricall
Destination: /home/john/Projects/lyricall/_site
Incremental build: disabled. Enable with --incremental
Generating...
Jekyll Feed: Generating feed for posts
Liquid Exception: undefined method `parameterize' for "Žďořšťáčik":String in feed.xml
bundler: failed to load command: jekyll (/home/john/.gem/ruby/3.0.0/bin/jekyll)
/usr/lib/ruby/gems/3.0.0/gems/jekyll_custom_permalink-0.0.1/lib/jekyll_custom_permalink/custom_permalink.rb:20:in `block in url_template': undefined method `parameterize' for "Žďořšťáčik":String (NoMethodError)
What am I doing wrong ? How can I use this method which should be part of a string class but apparently it is not ? How can I achieve same result without ruby on rails framework ?
INFO:
jekyll 4.1.1
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-linux]
Thank you for help
Rails additions to base Ruby classes, like String#parameterize, are part of the Active Support Core Extensions. The activesupport gem can be installed and used independent of Rails.
To keep the default footprint low, ActiveSupport allows you to require only the individual extensions you want to use. In your case, you will need to require the string inflection extensions:
require 'active_support/core_ext/string/inflections'
"Kurt Gödel".parameterize
=> "kurt-godel"

ruby on rails - cannot load such file -- serialport

I am trying to use serial port by ruby on rails. I use require 'serialport'. I installed gem serialport.
I have got this error:
cannot load such file -- serialport
and this line is highlighted:
require 'serialport'
This is my script:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
def hello
render text: "hello1, world!"
end
def cmd
require 'serialport'
#result = params[:parametr]
#dioda = params[:dioda]
#params for serial port
port_str = "/dev/ttyACM0" #may be different for you
baud_rate = 9600
data_bits = 8
stop_bits = 1
parity = SerialPort::NONE
sp = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity)
case #result
when "1"
render html: "<strong>Led_on</strong>".html_safe
when "0"
render html: "<strong>Led_off</strong>".html_safe
when "sos"
render html: "<strong>Led_sos</strong>".html_safe
end
sleep 4
puts sp.readlines
end
end
If you're using Rails, you need to put gem 'serialport' in your Gemfile and then run bundle install.
Problem solved by changing configuration of passenger which used wrong ruby interpreter. When I checked as a user in command line everything seemed to be ok, but using Apache/Passenger was an error, everything because different ruby interpreters used in these two situations.

Capistrano 3 use login shell

I ve read this nice explanation of login/nonlogin, interactive/noninteractive shells http://capistranorb.com/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/. But I found nowhere, how to run capistrano 3 in specific shell. I have tried options like:
set :pty, true # non-login, interactive but does not load .bashrc
set :default_shell, '/bin/bash --login'
set :shell, '/bin/bash --login'
but nothing helped. Thanks.
I know this is quite an old question, but the below shows how to open the SSHKit class and enable login shell, for capistrano.
# backend/sshkit.rb
module SSHKit
class CommandMap
class SuffixProvider
def initialize
#storage = CommandHash.new
end
def [](command)
#storage[command] ||= []
#storage[command]
end
def to_s(command)
self.[](command).join(" ")
end
end
def [](command)
cmd = []
if prefix[command].any?
prefixes = prefix[command].map{ |prefix| prefix.respond_to?(:call) ? prefix.call : prefix }
cmd.push(prefixes.join(" "))
end
cmd.push(#map[command])
cmd.join(" ")
end
def suffix
#suffix ||= SuffixProvider.new
end
end
class Command
def to_s
[SSHKit.config.command_map[command.to_sym], *Array(args), SSHKit.config.command_map.suffix.to_s(command.to_sym)].compact.join(' ')
end
end
end
Now you can define SSHKit command maps to enable bash --login for a specific command.
SSHKit.config.command_map[:rvm].prefix("bash --login '")
SSHKit.config.command_map[:rvm].suffix("'")
Now you can use :rvm command like below.
execute :rvm, :use, '2.2.2', '--install'
# => bash --login 'rvm use 2.2.2 --install'
I've written a blog post which explains this further. I would however recommend you use the login shell only when you must require it.
I have not found an answer for you...
But what I did was follow advice from A word about PTYs:
When Capistrano makes a connection it is a non-login, non-interactive shell. This was not an accident!
Maybe you need something that has been set in your .bash_profile as part of an interactive login? Move it to your .bashrc as that will be called by capistrano.

Defining actions for SimpleForm and rails

I'm getting this odd error, as if SimpleForm isn't even installed:
undefined method `simple_form_for'
SimpleForm IS in my gemfile and I've installed:
Using simple_form (2.0.2)
I'm running on the Pow server, so it's restarting every time.
#events_controller.rb
class admin::EventsController < ApplicationController
def new
#event = Event.new
end
#Event.rb
class Event
include Mongoid::Document
field :summary
field :start_date
field :end_date
end
#new.html.haml
= simple_form_for [:admin, #event] do |f|
= f.input :summary
= f.input :start_date
= f.input :end_date
Any ideas why it seems like SimpleForm isn't even installed?
Did you run the generator after you installed the gem? In your console you need to run this:
rails generate simple_form:install
I tried the command:
rails generate simple_form:install
And - it didn't run. Instead the output looked like I gave rails an ill-formed command line and it gave back a copy of the usage file.
Then, within RubyMine, I tried it again - this time got an error traceback - first line is shown below:
/home/user1/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.0/lib/rails/generators/base.rb:265:in `const_defined?': wrong constant name SimpleForm:installGenerator
After commenting out the lines 265-269 in base.rb:
# if last && last.const_defined?(last_name.camelize, false)
# raise Error, "The name '#{class_name}' is either already used in your application " <<
# "or reserved by Ruby on Rails. Please choose an alternative and run " <<
# "this generator again."
# end
and running the command again, I got:
/home/user1/.rvm/rubies/ruby-2.0.0-p247/bin/ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /home/user1/RubymineProjects/TravelAid/bin/rails generate generator simple_form:install -s
create lib/generators/simple_form:install
create lib/generators/simple_form:install/simple_form:install_generator.rb
create lib/generators/simple_form:install/USAGE
create lib/generators/simple_form:install/templates
Process finished with exit code 0
This looks pretty good, but I haven't gone back to check if simple_form works yet.
Under lib/generators, I have:
simple_form
templates
simple_form_generator.rb
USAGE
simple_form.install
templates
simple_form.install_generator.rb (created about 18 minutes ago - consistent with new)
USAGE
I am running Rails 4.0.0 and ruby-2.0.0-p247 within Rubymine

How to show all asked-for Translation Strings in Rails?

When Rails functions are asking for a translation (I18n.translate), I don't want to analyze their code in order to get the exact scopes etc.
How can I add a debug output into the console for every string that was asked for?
Examples:
I18n.t 'errors.messages.invalid', :scope => :active_record
# Translation for 'activerecord.errors.messages.invalid' (not) found
label(:post, :title)
# Translation for 'activerecord.attributes.post.title' not found
# Translation for 'views.labels.post.title' not found
This is not a very elegant solution, but it's worked for me. I've created an initialiser:
require 'i18n'
if (Rails.env.development? || Rails.env.test?) && ENV['DEBUG_TRANSLATION']
module I18n
class << self
def translate_with_debug(*args)
Rails.logger.debug "Translate : #{args.inspect}"
translate_without_debug(*args)
end
alias_method_chain :translate, :debug
end
end
end
You can then run commands like the following:
$ DEBUG_TRANSLATION=true rake cucumber
...and you'll see all the translations being attempted dumped to STDOUT. I don't consider this production code though, so I've kept it in a Gist, and not checked it into my main project source control at this stage.
Noddy, but it does the job.
Just a small change to put I18n debug messages in the log:
substitute this line:
puts "Translate: #{args.inspect}"
with
Rails.logger.debug "Translate : #{args.inspect}"

Resources