rails generate migration : no more version number - acts_as_archive compatibility? - ruby-on-rails

When I do a:
rails generate migration xxx
I get : ... create db/migrate/_xxx.rb
No timestamp and not any kind of numbering.
I tried:
rake db:migrate:reset -> no change
rake db:version -> correct value (20120509143011)
add config.active_record.timestamped_migration=false -> same problem (so i removed this line)
I'm using rails 3.2 - ruby 1.9.2 - rvm - mysql
Any idea?

Problem corrected ... but i'm not sure why ;-(
The last thing i did was to remove the gem "act_as_archive". then i generated a migration to remove the corresponding table and, my timestamp were back !
I did this 2 or 3 times (adding/removing the gem), and the problem is reproductible (in my project at least)
So I suppose this is a compatibility problem with acts_as_archive gem.
I hope this will help others.

The issue is the version of the 'also_migrate' gem that the acts_as_archive uses (0.35). The next version (0.36) fixes the problem. If memory serves I believe the method_missing alias was not returning a value from whatever operation it performed

Related

Rails database migrations problem 4.2 to 5.0 - boolean but default expression is of type integer

O.k. so I finally got a rails server to load with Rails 5.0.0 and ruby 2.5.8 (I'm upgrading from ruby 2.2.4 and rails 4.2.0).
I don't have any sll issues.
I'm now at the "ActiveRecord::PendingMigrationError" level.
Basically I haven't created the tables in my db (the db is already created in postgres).
When I run the bin/rails db:migrate RAILS_ENV=development I get the following:
PG::DatatypeMismatch: ERROR: column "root_comment" is of type boolean but default expression is of type integer HINT: You will need to rewrite or cast the expression.
I've read a ton, and it seems rails 5 changed both migration scripts and how to define columns in postgres.
Do I need to label my migration script with something like [4.2 or 5.0] or do I actually need to change the type (further screwing up my app)?
Thanks in advance.

How to duplicate object "by value" in Rails?

I need to duplicate a product in my spree application. So
def my_duplicate_product(product)
product.dup.tap do |new_product|
new_product.slug = "#{product.slug}-#{rand(1000)}"
...
This code causes the original product#slug to be changed.
What am I supposed to do to get a copy of that particular product and leave the original unchanged?
Rails version: 4.0.3
Update:
The problem is not in Ruby, nor Rails — it's all about globalize gem (v. 4.0.0).
This error was fixed in 4.0.3.
It realy broke #dup so some values were "shared" between the original model and the duplicated one.
See GitHub issue tracker for more information: https://github.com/globalize/globalize/pull/352
Maybe clone works:
def my_duplicate_product(product)
product.clone.tap do |new_product|
new_product.slug = "#{product.slug}-#{rand(1000)}"
Clone method on ruby doc
Update globalize gem to 4.0.3
See GitHub issue tracker for more information: https://github.com/globalize/globalize/pull/352

Does Rails 4 have support for OR queries

So in Rails 4 the long desired feature to use not queries has been added.
Article.where.not(title: 'Rails 3')
Has similar support been added for or queries, or are they planning to make it. I couldn't find anything by browsing through the release notes.
Obviously I tried
Article.where(title: 'Rails 3').or(title: 'Rails 4')
But that does not work.
Article.where(title: ['Rails 3', 'Rails 4'])
is how you'd do that in Active Record.
It's not possible to replicate any arbitrary SQL query using "Rails-y" syntax. But you can always just pass in literal sql.
So you could also do:
Article.where("articles.title = 'Rails 3' OR articles.title = 'Rails 4'")
This now works in Rails 5:
Article.where(title: 'Rails 3').or(Article.where(title: 'Rails 4'))
Code example in Rails's source.
The most common alternative is already answer by #gregates
Recently there has been pull request in rails source
Add #any_of query method to active_record
Which adds or functionality to activerecord
the contributor has already created a gem incase its not accepted
its rails 3.2 and 4 compatible
https://github.com/oelmekki/activerecord_any_of
I havent tried it yet but soon wish to use it looks good to me.
I know that this is an old thread, but anyone else looking for a solution to this problem might find this code helpful:
Article.where(title: ["Rails 3", "Rails 4"])
Maybe that will help you get someone going in the right direction without having to risk sql injection.
It seems that the rails master branch is now supporting OR queries. https://github.com/rails/rails/pull/16052
I assume it will be in the framework with the next major release.
Rails 5 will support it but you can use this backport for Rails 4.2 : https://github.com/Eric-Guo/where-or

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'

rake db:migrate doesn't detect new migration?

Experienced with Rails / ActiveRecord 2.1.1
You create a first version with (for example) ruby script\generate scaffold product title:string description:text image_url:string
This create (for example) a migration file called 20080910122415_create_products.rb
You apply the migration with rake db:migrate
Now, you add a field to the product table with ruby script\generate migration add_price_to_product price:decimal
This create a migration file called 20080910125745_add_price_to_product.rb
If you try to run rake db:migrate, it will actually revert the first migration, not apply the next one! So your product table will get destroyed!
But if you ran rake alone, it would have told you that one migration was pending
Pls note that applying rake db:migrate (once the table has been destroyed) will apply all migrations in order.
The only workaround I found is to specify the version of the new migration as in:
rake db:migrate version=20080910125745
So I'm wondering: is this an expected new behavior?
You should be able to use
rake db:migrate:up
to force it to go forward, but then you risk missing interleaved migrations from other people on your team
if you run
rake db:migrate
twice, it will reapply all your migrations.
I encounter the same behavior on windows with SQLite, it might be a bug specific to such an environment.
Edit -- I found why. In the railstie database.rake task you have the following code :
desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
task :migrate => :environment do
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end
Then in my environment variables I have
echo %Version% #=> V3.5.0f
in Ruby
ENV["VERSION"] # => V3.5.0f
ENV["VERSION"].to_i #=>0 not nil !
thus the rake task calls
ActiveRecord::Migrator.migrate("db/migrate/", 0)
and in ActiveRecord::Migrator we have :
class Migrator#:nodoc:
class << self
def migrate(migrations_path, target_version = nil)
case
when target_version.nil? then up(migrations_path, target_version)
when current_version > target_version then down(migrations_path, target_version)
else up(migrations_path, target_version)
end
end
Yes, rake db:migrate VERSION=0 is the long version for rake db:migrate:down
Edit - I would go update the lighthouse bug but I the super company proxy forbids that I connect there
In the meantime you may try to unset Version before you call migrate ...
This is not the expected behaviour. I was going to suggest reporting this as a bug on lighthouse, but I see you've already done so! If you provide some more information (including OS/database/ruby version) I will take a look at it.
I respectfully disagree Tom! this is a bug !! V3.5.0f is not a valid version for rake migrations. Rake should not use it to migrate:down just because ruby chose to consider that "V3.5.0f".to_i is 0 ...
Rake should loudly complain that VERSION is not valid so that users know what is up
(between you and me, checking that the version is a YYYYMMDD formated timestamp by converting to integer is a bit light)
[Damn IE6 that won't allow me to comment ! and no I can't change browser thanks corporate]
Jean,
Thanks a lot for your investigation. You're right, and actually I think you've uncovered a more severe bug, of species 'design bug'.
What's happening is that rake will grab whatever value you pass to the command line and store them as environment variables. The rake tasks that will eventually get called will just pull this values from the environment variable.
When db:migrate queries ENV["VERSION"], it actually requests the version parameter which you set calling rake. When you call rake db:migrate, you don't pass any version.
But we do have an environment variable called VERSION that has been set for other purposes by some other program (I don't which one yet). And the guys behind rake (or behind database.rake) haven't figured this would happen. That's a design bug. At least, they could have used more specific variable names like "RAKE_VERSION" or "RAKE_PARAM_VERSION" instead of just "VERSION".
Tom, I will definitely not close but edit my bug report on lighthouse to reflect these new findings.
And thanks again Jean for your help. I've posted this bug on lighthouse like 5 days agao and still got no answer!
Rollo

Resources