I have a model called Task.
rails runner -e development "Task.myClassMethod"
Results in this:
Please specify a valid ruby command or the path of a script to run.
Run 'bin/rails runner -h' for help.
undefined method `myClassMethod' for Thor::Command:Class
This works in any of my other models. I tried clearing out my Task model:
class Task < ApplicationRecord
def self.myClassMethod
pp 'Hello'
end
end
I've also tried running rails app:update:bin per this thread: https://github.com/javan/whenever/issues/663
But still getting the same errors. Is this a naming conflict?
Related
I'm trying to make Capistrano deploy script.
In my Capfile I make sure all rake tasks are included
# Load tasks
Dir.glob('config/capistrano_tasks/*.rake').each { |r| import r }
Next I have a 'migrations.rake' containing:
namespace :fileservice do
task :migrate do
within release_path do
info 'Doing migrations'
execute :php, fetch(:symfony_console_path), 'doctrine:migrations:migrate', '--no-interaction', fetch(:symfony_console_flags)
end
end
end
In my deploy.rb I call the task at the very end with:
after 'deploy:publishing', 'fileservice:migrate'
For some reason I keep getting an error saying:
NoMethodError: undefined method `within' for main:Object
I have no idea where to look or what might be wrong... When googling I get a lot of "NoMethodError" hits but none about the 'within' method and most are general Ruby errors.
Where should "within" be defined? I dat a ruby on rails thing? Or capistrano?
Hopefully someone knows where to start looking or which library / script to include!
UPDATE: I just discovered that none of the methods work. When removing lines I got the same error for "info" and "execute".... So I guess somewhere, something is missing.....
You need to tell Capistrano where (i.e. on what servers) to run your SSH commands. Do this using an on block, as follows:
namespace :fileservice do
task :migrate do
on roles(:db) do
within release_path do
info 'Doing migrations'
execute :php, fetch(:symfony_console_path), 'doctrine:migrations:migrate', '--no-interaction', fetch(:symfony_console_flags)
end
end
end
end
Replace roles(:db) as appropriate for your task, depending on where you want the commands to be run. The expression on roles(:all) do ... end, for example, will run the commands on all servers.
You can also follow the official documentation at http://capistranorb.com, or the Capistrano README, both of which show examples of the task/on/execute syntax.
As you already got the answer but Let me put the bulb from basic.
SSHKit was actually developed and released with Capistrano 3, and it’s basically a lower-level tool that provides methods for connecting and interacting with remote servers; it does all the heavy lifting for Capistrano, in other words.
There are four main methods you need to know about.
on(): specifies the server to run on
within(): specifies the directory path to run in
as(): specifies the user to run as
with(): specifies the environment variables to run with
Typically, you’ll start a task by using an on() method to specify the server on which you want your commands to run. Then you can use any combination of as(), within(), and with() methods, which are repeatable and stackable in any order.
Hope this help you
I am developing a mailing web application in Ruby on Rails and I am in front of an issue with delayed_job gem:
In the settings of my application, I give the ability for the customer to update the email address from where mailing are sent. But I discovered there was something like a cache from delayed_job which doesn’t use the update email address for the « from » header.
When I use the delayed_job task by Capistrano manually it works so I tried to add a callback after_update in my model to handle the restart of delayed_job but without any success.
Capistrano command:
cap <my_env> delayed_job:restart # this works but it’s a manual command so useless in my case
What I tried is to dynamically restart delayed_job from the model:
class Setting < ActiveRecord::Base
after_save :restart_delayed_job
def restart_delayed_job
if email_changed?
system "RAILS_ENV=#{Rails.env} do bundle exec bin/delayed_job -n 1 restart"
end
end
end
My Mailing class:
class MyMailer < ApplicationMailer
default from: Setting.first.email # After updating the email value in setting, it still the old one used.
# more code skipped
end
Does anyone knows how can I restart delayed_job from Rails ?
Is there a way to do it exclusively in Ruby without writing shell script ?
In order to help me to understand better, is there several instance of delayed_job (one by website in the server) or one for all website ?
Thanks for your help !
My project:
- Rails 4.2.5
- Ruby 2.2.2
- ActiveAdmin 1.0.0 pre2
- Delayed job 4.1.1
- Capistrano 3.4.0
The solution was to move the from header into the mail function.
The reason is the default from is set only once when the application start and cannot be changed this way.
mail(from: email, subject: subject, ...) do
# skipped code
end
Here is the answer who helped me to understand that: https://github.com/collectiveidea/delayed_job/issues/882
I have a script written with jRuby and I need this script to be executed from rails app (which runs on MRI ruby). I have code like this:
class User < ActiveRecord::Base
def run_script!
system "jruby /path/to/my/script/script.rb #{id}"
end
end
and it works in development! But on Ubuntu production server it returns nil and I have no idea how to make it work.
From the Kernel#system documentation:
Returns nil if command execution fails. An error status is available in $?.
So what does $? tell you?
How do I run Prawn scripts with Delayed_job.
(Currently using Bj but not supported in Rails3)
This code does not work.
/lib/report_job.rb
class ReportJob < Struct.new(:prawn_script_name , :account_id )
def perform
bundle exec rails runner "#{Rails.root}/jobs/#{prawn_script_name}.rb #{#current_user.account_id} "
end
/reports_controller.rb
def generate_report(prawn_script_name)
Delayed::Job.enqueue(ReportJob.new("#{prawn_script_name}.rb","#{#current_user.account_id}"))
end
delayed_job table is populated as expected.
--- !ruby/struct:ReportJob
prawn_script_name: statements.rb
account_id: '18'
Error in last_error field.
{undefined method `runner' for ReportJob:0xc28f080
Any suggestions?
I think there are several misunderstandings here:
you meant to call runner from outside your app, e.g., in a shell script or command line. in other words, bundle exec rails runner are all commands and arguments of commands, not ruby methods or variables. runner is the first expression that is eval'd inside your perform method, hence your error.
rails runner just brings up your apps environment and evals the string or path argument given.
note account_id within the perform task, another mistake in your code I guess.
What you wanted to do could be a simple system call.
It seems your prawn script needs the environment, so simply calling
system "ruby #{Rails.root}/jobs/#{prawn_script_name}.rb #{account_id}"
won't work.
Now you could surely execute the script with runner from your project directory.
system "bundle exec rails runner #{Rails.root}/jobs/#{prawn_script_name}.rb #{account_id}"
but doing this via a system call within your environment is quite redundant. Delayed jobs already have access to your rails environment. so just simply load them.
class ReportJob < Struct.new(:prawn_script_name , :account_id )
def perform
load "#{Rails.root}/jobs/#{prawn_script_name}.rb"
end
end
hope this helps
How can I run a single test from a Rails test suite?
rake test ANYTHING seems to not help.
NOTE: This doesn't run the test via rake. So any code you have in Rakefile will NOT get executed.
To run a single test, use the following command from your rails project's main directory:
ruby -I test test/unit/my_model_test.rb -n test_name
This runs a single test named "name", defined in the MyModelTest class in the specified file. The test_name is formed by taking the test name, prepending it with the word "test", then separating the words with underscores. For example:
class MyModelTest < ActiveSupport::TestCase
test 'valid with good attributes' do
# do whatever you do
end
test 'invalid with bad attributes' do
# do whatever you do
end
end
You can run both tests via:
ruby -I test test/unit/my_model_test.rb
and just the second test via
ruby -I test test/unit/my_model_test.rb -n test_invalid_with_bad_attributes
Run a test file:
rake test TEST=tests/functional/accounts_test.rb
Run a single test in a test file:
rake test TEST=tests/functional/accounts_test.rb TESTOPTS="-n /paid accounts/"
(From #Puhlze 's comment.)
For rails 5:
rails test test/models/my_model.rb
Thanks to #James, the answer seems to be:
rails test test/models/my_model.rb:22
Assuming 22 is the line number of the given test. According to rails help:
$ rails test --help
You can run a single test by appending a line number to a filename:
bin/rails test test/models/user_test.rb:27
Also, please note that your test should inherit from ActionDispatch::IntegrationTest for this to work (That was my mistake):
class NexApiTest < ActionDispatch::IntegrationTest
.
.
.
Rails 5
I used this way to run single test file (all the tests in one file)
rails test -n /TopicsControllerTest/ -v
Another option is to use the line number (which is printed below a failing test):
rails test test/model/my_model.rb:15
In my situation for rake only works TESTOPTS="-n='/your_test_name/'":
bundle exec rake test TEST=test/system/example_test.rb TESTOPTS="-n='/your_test_name/'"
To run a single test in the actual Rails suite:
bundle exec ruby -I"railties/test" actionpack/test/template/form_options_helper_test.rb
That was a silly midnight question of mine. Rails kindly prints the command it is executing upon rake test. The rest is a cut and paste exercise.
~/projects/rails/actionpack (my2.3.4)$ ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/controller/base_test.rb"
The best way is to look directly into the guides: http://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#running-tests
cd actionmailer
bundle exec ruby -w -Itest test/mail_layout_test.rb -n test_explicit_class_layout
If you want to run a single test, you can just run them as a regular Ruby script
ruby actionmailer/test/mail_layout_test.rb
You can also run a whole suite (eg. ActiveRecord or ActionMailer) by cd-ing into the directory and running rake test inside there.
To re-run a test that just failed, copy-n-paste the failed test name into
rails test -n [test-name]
EXAMPLE
When your test suite reports this:
> rails test
...
Error:
PlayersControllerTest#test_should_show_player:
ActionView::Template::Error: no implicit conversion from nil to integer
you rerun the failing test with this:
rails test -n PlayersControllerTest#test_should_show_player
If rake is running MiniTest, the option is --name instead of -n.
rake test TEST=test/unit/progress_test.rb TESTOPTS="--name=testCreate"
First, access the folder of the lib you want to test(this is important) and then run:
~/Projects/rails/actionview (master)$ ruby -I test test/template/number_helper_test.rb
Rails folder
bundle install
bundle exec ruby -I"activerecord/test" activerecord/test/cases/relation/where_test.rb
Note you need to load appropriate folder: "activerecord/test" (where you have test)