How to invoke rails migration generator programmatically? - ruby-on-rails

Simply Running rails g from command line suffers from long time of pre-loading. I want to fast generate multiple migrations from a running rails c, so I tried:
require 'rails/generators'
Rails::Generators.invoke('migration',['user_book_list_followings'],{:behavior=>:invoke, :destination_root=>Rails.root})
You ask where did I get that :behavior and :destination_root arguments? Well, I pried at the Rails::Generators#invoke execution point when I run the generator from the command and recorded the exact arguments.
However, the funny thing was, I was presented with a error saying:
No value provided for required options '--orm'
Did I miss anything? (I was on Rails 3.2.3)

require 'rails/generators'
Rails::Generators.invoke("active_record:migration", ["create_something", "list_order:string", "name:string"], {migration: true, timestamps: true})

One solution to speed up callings rails g, is using spring.
Spring is a Rails application preloader. It speeds up development by keeping your application running in the background so you don't need to boot it every time you run a test, rake task or migration.

Related

After upgrade to Rails 4: Specs fail in combination while passing in isolation

I'm struggling with this for quite a while now: I'm trying to upgrade an app from Rails 3.2 to Rails 4. While on Rails 3.2 all specs are passing, they fail under certain conditions in Rails 4.
Some specs are passing in isolation while failing when run together with other specs.
Example Video
https://www.wingolf.org/ak-internet-files/Spec_Behaviour.mp4 (4 mins)
This example video shows:
Running 3 specs using :focus–––green.
Running them together with another spec–––two specs passing before now fail.
Running the 3 specs, but inserting two empty lines–––one spec fails.
Undo does not help when using guard.
focus/unfocus does not help.
Restarting guard does not help.
Running all specs and then running the 3 specs again does help and make them green again. But adding the other task makes two specs fail, again.
As one can see, some specs are red when run together with other specs. Even entering blank lines can make a difference.
More Observations
For some specs, passing or failing occurs randomly when run several times.
The behavior is not specific to one development machine but can be reproduced on travis.
To delete the database completely between the specs using database_cleaner does not help.
To Rails.cache.clear between the specs does not help.
Wrapping each spec in an ActiveRecord::Base.transaction does not help.
This does occur in Rails 4.0.0 as well as in Rails 4.1.1.
Using this minimal spec_helper.rb without spring or anything does not help.
Using guard vs. using bundle exec rspec some_spec.rb:123 directly doesn't make a difference.
This behavior goes for model specs, thus doesn't have to do anything with parallel database connections for features specs.
I've already tried to keep as many gems at the same version as in the (green) Rails-3.2 branch, including guard, rspec, factory_girl, etc.–––does not help.
Update: Observations Based on Comments & Answers
Thanks to engineerDave, I've inserted require 'pry'; binding.pry; into one of the concerning specs. Using the cd and show-source of pry, it was ingeniously easy and fun to narrow down the problem: Apparently, this has_many :through relation does not return objects when run together with other specs, even when called with (true).
has_many(:groups,
-> { where('dag_links.descendant_type' => 'User').uniq },
through: :memberships,
source: :ancestor, source_type: 'Group'
)
If I call groups directly, I get an empty result. But if I go through the memberships, the correct groups are returned:
#user.groups # => []
#user.groups(true) # => []
#user.memberships.collect { |m| m.group } # returns the correct groups
Has Rails changed the has many through behavior in Rails 4 in a way that could be responsible? (Remember: The spec works in isolation.)
Any help, insights and experiences are appreciated. Thanks very much in advance!
Code
Current master branch on Rails 3.2––all green.
Rails-4 branch––strange behavior.
The file/commit seen in the video––strange behavior.
All specs passing on travis for Rails 3.2.
Diff of the Gemfile.lock (or use git diff master..sf/rails4-minimal-update Gemfile.lock |grep rspec)
How to Reproduce
This is how one can check if the issue still exists:
Preparation
git clone git#github.com:fiedl/wingolfsplattform.git
cd wingolfsplattform
git checkout sf/rails4-minimal-update
bundle install
# please create `config/database.yml` to your needs.
bundle exec rake db:create db:migrate db:test:prepare
Run the specs
bundle exec rspec ./vendor/engines/your_platform/spec/models/user_group_membership_spec.rb
bundle exec rspec ./vendor/engines/your_platform/spec/models/user_group_membership_spec.rb:213
The problem still exists, if the spec :213 is green in the second call but is red when run together with the other specs in the first call.
Based on that you're using:
the should syntax
that you indicate you've upgraded recently (perhaps a bundle update?)
that your failure messages indicate a NilObject error.
Is something like this perhaps what is causing it?
https://stackoverflow.com/a/16427072/793330
Are you are calling an object in your test which hasn't been instantiated yet?
I think this might be an rspec 3 upgrade issue where should is deprecated.
Have you ruled out an rspec gem upgrade to the new rspec 3 syntax (2.99 or 3.0.0+) as the culprit?
"Remove support for deprecated expect(...).should. (Myron Marston)"
IMO this behavior would not be caused by a Rails 4 update as its centered around your test suite.
Update (with pry debug):
Also you could use the pry gem to get a window into what is going on in your specs.
Essentially you can put a big "stop" sign (similar to a debug break) right before the spec executes to get a handle on the environment at that point.
it {
require 'pry'; binding.pry
should == something
}
Although beaware sometimes these pry calls wreck havoc on guard's threading and you have to kill it with CTRL+Z and then kill -9 PID that shows.
Update #2: Looking at updated answer.
You might be running up against FactoryGirl issues based on your has_many issue
You may need to trigger a before action in your Factory to pre-populate the associated record. Although this could get messy, i.e. here be monsters, you can trigger after and before callbacks in your factory that will bring these objects into being.
after(:create) do |instance|
do stuff here
end

Delayed_job won't make any changes to database

I am having many problems running DJ. Primarily, I cannot get delayed_job running any methods that change the database. I am testing locally with a sqlite3 database, DJ 3.0.0, and I even added the delayed_job_active_record gem.
I have, for example, tried to run the following method in the background:
#user = User.find(1)
#user.delay.recorder_method
Where this method is:
def recorder_method
self.relevant_field +=1
update
end
This creates a delayed job, and the handler has the appropriate info for the user and the appropriate method name. The script runs the job, thinks it has succeeded and thus deletes the record from the delayed_job table. BUT the user is unchanged (the database is unchanged).
What on earth is going wrong? Note that, when I run the same code ("#user.delay.recorder_method") from rails console, it works.. and the difference is the handler created by the rails console call is:
--- !ruby/object:Delayed::PerformableMethod
object: !ruby/ActiveRecord:User
attributes:
... (attribute info and rest of file)
Whereas the one created in by the call in a controller action is:
--- !ruby/struct:Delayed::PerformableMethod
object: !ruby/ActiveRecord:User
attributes:
Not the difference in line 1 of both things (ruby/object vs ruby/struct.. the former works and the latter doesn't). Maybe this is something that might signal what is going wrong. Any ideas, anybody?
Your Rails app is running an old version of the DJ gem and your console is running a new one. About six months ago, Delayed::PerformableMethod was refactored from a Struct into a regular class: https://github.com/collectiveidea/delayed_job/commit/7b8a79a72c0ee5d8bac4bc0b183d1cce9cedff85 (So your Rails app is running a gem at least six months old and your console is running one newer than that).
This is an easy fix. First update the appropriate line in your Rails Gemfile. You'll see a line like this:
gem 'delayed_job_active_record'
If it has a version specification, make sure it's updated to the newest. Then from the command line (in the Rails root), run:
bundle update delayed_job_active_record
For anyone interested, removing the following lines from boot.rb solved this issue for me:
require 'yaml'
YAML::ENGINE.yamler = 'syck'

Thinking Sphinx in cucumber tests

I'm using Rails 3, Thinking-sphinx 2.0.2 and Cucumber 0.10.2. I would like to test my thinking-sphinx search statements in my integration tests using Cucumber, but it seems very slow.
I've added to my env.rb file:
require 'cucumber/thinking_sphinx/external_world'
Cucumber::ThinkingSphinx::ExternalWorld.new
Cucumber::Rails::World.use_transactional_fixtures = false
As soon as I add these lines and run 'time rake cucumber' on a fresh project with no tests written yet it takes 48seconds (on a i7-930 with 12GB ram and an Intel SSD). If I take out the thinking_sphinx lines it takes 10 seconds.
Is this normal?
If so can I limit the loading of sphinx for anything with tag #slow?
What happens if you remove the last line (ie. set transactional fixtures back to true). The TS docs are a little out of date - refer to my blog post instead.
That said, the second line could be the cause of the slowness - as it'll automatically configure, index and start Sphinx - and then stop it once the task is finished.

Ruby on rails, run a method on server start 2.3

I want to run a method, on the startup of the rails server. It's a model method.
I tried using config/initializers/myfile.rb, but the method was invoked during migrations, so it SELECTed from a nonexistant table.
Tried environment.rb also, but the class does not exist yet (and will probably have the same problem with migrations)
I don't know where to put that method, so it'll run only on server startup and not during migrations.
There are some things you could do to actually improve this a bit. The issue is that you are running this code when rake loads your environment, but you really only want to run this when the environment is loaded by an instance of your web server. One way to get around this is to set a value when rake loads your environment, and when that value is set, to not execute your initializer code. You can do this as follows:
task :environment => :disable_initializer
task :disable_initializer do
ENV['DISABLE_INITIALIZER_FROM_RAKE'] = 'true'
end
#In your initializer:
ENV['DISABLE_INITIALIZER_FROM_RAKE'] || MyModel.method_call
There is no way to avoid this from my understanding. You can put the initializer code that relies on the new table in a rescue block to quiet things down so others can run migrations.
Try putting your method call in boot.rb, in the run method after the Rails::initializer call. I don't have rails in front of me right now because I'm at work but I think that the whole environment should be loaded by that point and you can run methods on the framework.
I found this to work quite well:
if File.basename($0) == "rails" && ARGV == []
It also detects "rails generate .."

unable to save a model from rake task

I am writting a rake task that would connect to a legacy ORACLE database, get some 'issues' records from a helpdesk application, apply some transformation and store it in another database (Redmine).
The problem is that even though the script runs smoothly on Windows, it fails to run on RHEL 5. The library files are all installed on RHEL 5 and there are no connection errors as such. The script fails on a line '_issue.save' (where _issue is a model of type Issue 0n Redmine)!! There is no error (Just that _issue.save returns false). I've been stuck for the last 2 days on this one.
Any suggestions would be extremely helpful.
I am using Rails 2.1.2, Ruby 1.8.6 (patch level 111) and Rake 0.8.1
Thanks in advance.
No errors, but save returns false means validation might have failed. You can output the validation errors like so:
_issue.errors.each_full { |msg| puts msg }
Here's a bit more info on the each_full method.
I would create some tests and run them on the RHEL server to see where the issue is. I would use RSPEC, but test/unit can get you there as well.

Resources