Works in SQLite but not in PostGreSQL... attribute IS NOT 1 - ruby-on-rails

I have a statement in my code:
RentalItem.last.maintenance_orders.where("status_id IS NOT 2").present?
Works fine in development mode, but not in PostGreSQL in production. Trouble is, that syntax was the only way of making the code work because in my statement, if a child maintenance_order had a status_id of nil, then I want it to be found by the .present? command. Other syntaxes were ignoring nil. See this question here: Rails ActiveRecord find children where attribute is NOT a given value
Any ideas on how to change this syntax?

Try:
RentalItem.last.maintenance_orders.where("status_id <> 2 or status_id is null").present?

Related

Updating a Rails model's attributes through mongoid using normal persistence methods

I have been chasing an issue down for a while now, and still cannot figure out what's happening. I am unable to edit documents made from my gem through normal persistence methods, like update or even just editing attributes and calling save.
For example, calling:
Scram::Policy.where(id: a.id).first.update!(priority: 12345)
Will not work at all (there are no errors, but the document has not updated). But the following will work fine:
Scram::Policy.collection.find( { "_id" => a.id } ).update_one( { "$set" => {"priority" => 12345}})
I am not sure what I'm doing wrong. Calling update and save on any other model works fine. The document in question is from my gem: https://github.com/skreem/scram/blob/master/lib/scram/app/models/policy.rb
I cannot edit its embedded documents either (targets). I have tried removing the store_in macro, and specifying exactly what class to use using inverse_of and class_name in a fake app to reimplement these classes: https://github.com/skreem/scram-implementation/blob/master/lib/scram/lib/scram/app/models/policy.rb
I've tried reimplementing the entire gem into a clean fake rails application: https://github.com/skreem/scram-implementation
Running these in rails console demonstrates how updating does not work:
https://gist.github.com/skreem/c70f9ddcc269e78015dd31c92917fafa
Is this an issue with mongoid concerning embedded documents, or is there some small intricacy I am missing in my code?
EDIT:
The issue continues if you run irb from the root of my gem (scram) and then run the following:
require "scram.rb"
Mongoid.load!('./spec/config/mongoid.yml', :test)
Scram::Policy.first.update!(priority: 32) #=> doesn't update the document at all
Scram::Policy.where(id: "58af256f366a3536f0d54a61").update(priority: 322) #=> works just fine
Oddly enough, the following doesn't work:
Scram::Policy.where(id: "58af256f366a3536f0d54a61").first.update(priority: 322)
It seems like first isn't retrieving what I want. Doing an equality comparison shows that the first document is equal to the first returned by the where query.
Well. As it turns out, you cannot call a field collection_name or else mongoid will ensure bad things happen to you. Just renaming the field solved all my issues. Here's the code within mongoid that was responsible for the collision: https://github.com/mongodb/mongoid/blob/master/lib/mongoid/persistence_context.rb#L82
Here's the commit within my gem that fixed my issue: https://github.com/skreem/scram/commit/25995e955c235b24ac86d389dca59996fc60d822
Edit:
Make sure to update your Mongoid version if you have dealt with this issue and did not get any warnings! After creating an issue on the mongoid issue tracker, PersistenceContext was added to a list of prohibited methods. Now, attempting to use collection_name or collection as a field will cause mongoid to spit out a couple of warnings.
Fix commit: https://github.com/mongodb/mongoid/commit/6831518193321d2cb1642512432a19ec91f4b56d

Why is Rails runner not returning a result?

I am having problems with the Rails runner. When I try to use if, even by command line, it does nothing! it doesn't show error messages, nor results from actions.
For example, if I try
rails runner Credit.count
having defined the model Credit, and the method count as
Credit.first.update_attribute(:estado, "En proceso")
or even simpler tasks, the runner does nothing!
I've tried saying that the environment is development, but nothing works. Does anyone has any insights? Am I doing something wrong?
Edit: I am watching the database, that's the problem, there is no update. I changed the value of the column "estado" for the first element to something other than "En proceso", however, no matter how many times I use the runner, the db doesn't show any change at all.
rails runner: runner runs Ruby code in the context of Rails non-interactively
update_attribute : it only return true or false, if you want to output the result, you can use "puts" or "p".
For example,
$ rails r "User.first" #no output, even it will return a user object
$ rails r "puts User.first" # you can use "puts" get the output
#<User:0x007f8a2c76e608>
if you just written Credit.first.update_attribute(:estado, "En proceso") in console, you shouldn't have results, but you could see result in DB, for checking if update_attribute really update it you could write as update_attribute! also you could just write:
p Credit.first.update_attribute(:estado, "En proceso") which should print true or false to console
Turns out I am an idiot.
First, I had to change the name of the method, calling Credit.count calls the default count method, so I changed it to myMethod.
After that, I was able to use puts function and update the database easily :)

Rails PostgreSQL array can't iterate

I wrote a helper method for my controller to iterate through an attribute, being represented as an array using PostgreSQL.
def format_cf array
nums = ""
array.each { |c| nums += "#{c}, " }
unless nums.blank?
nums.chop!.chop!
end
nums
end
This way, I don't get the messy {} chars in my view. I'm implementing an empty value for this attribute as the string '{}', meaning that's what I set the default value to in my migration. This hasn't been a problem for my development environment, as it interprets that as an empty array. However, now in production, this helper method is throwing an error saying
ActionView::Template::Error (undefined method `each' for "{}":String)
Is my implementation wrong here, or can anyone think of some obscure setting I may have overlooked when comparing my development.rb and production.rb?
EDIT: 2013-04-11 9:00
I'm currently deploying using capistrano with unicorn and nginx
I'm going to guess you may have run into this bug as well, if you're using rails 4 https://github.com/rails/rails/issues/10432. Basically there's a bug in the Migrations system that turns :string, array: true into a normal :string directive. The joys of using edge stuff huh.
I gues you used taps to deploy tour database on heroku with
heroku db:push
Problem is that taps doesn't support Postgres array, and it ends up casting the column as a string. There are many workaround for that.
The one I used was to open a console on heroku
heroku run console
Then get a connection to the database
User.connection # or any of your models
And then execute raw sql with the connection#execute method in order to create a backup column, delete the current string column and recreate it as an array.
You'll probably find it more useful to use the import/export advised by heroku
And if you're not using heroku, then I' completely wrong, and I have no idea what your problem is :)

Rails 3 - Foreign Keys - Strings vs Symbols

I am in the process of learning Rails and I've ran into an interesting problem tonight.
I was creating a migration that would require an index on the foreign key:
Whenever I would run 'bundle exec rake db:migrate', I would receive this console error:
It looks as if it was trying to create the index before it was creating the reference.
The reason I believe this is because when I change the "subject" reference to a symbol:
The migration then suddenly works as expected!
This may just be the fact that I'm a total newby, but are symbols actually processed faster by Ruby than strings are?
Just curious - thanks!
This isn't a "faster" problem, or a problem of speed. The migrations are executed one line at a time, in order. The way you had it specified before simply didn't create the column correctly, hence when it got to the line where you create the index, the names didn't match up.
My guess is, with the string version it created the column name exactly as you spelled it, "subject" as opposed to subject_id when you use a symbol. Either way, you definitely had a name mismatch between when the column was created, and when the index was being built.
Always use symbols for this in your migrations, and you should be fine. Always check your schema.rb file, or browse the database using a GUI tool, after a migration to make sure the columns got created the way you expect, and with the data types you think they are, and you should be good.

Why do I have to add .to_i for Postgresql to know this field is an integer?

The following line works fine in MySQL, but in Postgresql I get a Rails error stating, "can't convert Fixnum to String".
viewable.update_attribute(:total_views, viewable.total_views.to_i + 1)
total_views is an integer field
Shouldn't Rails know to treat total_views as an integer even if I am using Postgresql?
The short answer is "yes" Rails should know how to deserialize that column as an integer. What version of Rails and what Postgres adapter are you using?
As a bonus, though, you can do the following to accomplish what you want:
viewable.increment(:total_views)
I'm not sure if you would have the same problem with the
update_attributes
method. Since the
update_attribute
method skips Rails validations.Try using the former, and you may get a better picture on what's going on behind the scenes.

Resources