rails where.not -- how to do it this way - ruby-on-rails

I want to return all of the profiles found except for one, the one of the current user. I was thinking of doing this from the model.
self.order('random()')
.where(:blahblah => blah)
So everything is working up until here
I added this part, and it doesn't work
.not(:email => "blah#blah.com")
And I am not sure why. The documentation shows queries that are like where.why(blah) and nothing like what I am doing. I am not sure where else to look. Thanks.
Getin NoMethodError
undefined method `not' for #

Depending on which rails version you are on,
if rails 3
self.order('random()').where('email != ?', "blah#blah.com")
if rails 4
self.order('random()').where.not(email: "blah#blah.com")

Related

Problems Implementing ActiveModel Dirty Rails 3.2.8

I want to check when attributes on a model have changed. I have attempted to check values != the value on the form before doing a save but that code is really ugly and is not working well at times. Same with using update_column which does not do the validations in my model class. If I use update_attributes without doing something else I will not be able to check when a field has been updated from my understanding. From my web research on Stack Overflow and other sites it appears that using ActiveModel Dirty is the way to go.
I have looked at this: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
My hope is to use this to check if boolean flags changed on a model after using update_attributes. I attempted to do the minimum implementation as described in the included link. I added the following to my ActiveRecord class:
include ActiveModel::Dirty
define_attribute_methods [:admin]
I tried adding the three attributes I wanted to keep track of. I started with just one attribute to see if I could get it working. I received the following error when I ran an rspec test. Once I removed the argument I had no errors.
Exception encountered: #<ArgumentError: wrong number of arguments (1 for 0)>
After I removed the argument I decided to include similar methods in my model using admin instead of name. Other Rspec tests broke on the save method. However I feel the problem is with how I am implementing ActiveModel Dirty.
I have read on other Stack Overflow posts where commenters stated that this was included in 3.2.8 so I upgraded from 3.2.6 to 3.2.8. I did not understand what that meant so after getting errors I decide just to leave the include ActiveModel::Dirty statement and try to use admin_changed? Of course it did not work.
I have not been able to find anything about how to initially set things up for this other than the link I included here. All the other research I have found assumes that the initial setup was correct and that updating to the current stable version of Rails would take care of their problems.
Any help would be appreciated on how to implement this. Doing the minimal implementation as stated in the link is not working. Maybe there is something else I am missing.
The problem appears to be that ActiveRecord redefines the define_attribute_methods method to accept 0 arguments (because ActiveRecord automatically creates attribute methods for every column in the database table): https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods.rb#L23
This overrides the define_attribute_methods method provided by ActiveModel: https://github.com/rails/rails/blob/master/activemodel/lib/active_model/attribute_methods.rb#L240
Solution:
I figured out a solution that worked for me...
Save this file as lib/active_record/nonpersisted_attribute_methods.rb: https://gist.github.com/4600209
Then you can do something like this:
require 'active_record/nonpersisted_attribute_methods'
class Foo < ActiveRecord::Base
include ActiveRecord::NonPersistedAttributeMethods
define_nonpersisted_attribute_methods [:bar]
end
foo = Foo.new
foo.bar = 3
foo.bar_changed? # => true
foo.bar_was # => nil
foo.bar_change # => [nil, 3]
foo.changes[:bar] # => [nil, 3]
However, it looks like we get a warning when we do it this way:
DEPRECATION WARNING: You're trying to create an attribute `bar'. Writing arbitrary attributes on a model is deprecated. Please just use `attr_writer` etc.
So I don't know if this approach will break or be harder in Rails 4...
See also:
Track dirty for not-persisted attribute in an ActiveRecord object in rails
https://github.com/adzap/validates_timeliness/issues/73
Try adding adding =, like this:
define_attribute_methods = [:admin]
That change worked for me. Not sure if it has something to do with this?

Understanding will paginate scopes/relations

Why does Post.page(1).total_pages result in:
Post.page(1).total_pages
undefined local variable or method `total_pages' for #<ActiveRecord::Relation:0x00000006a95230>
but
Post.scoped.page(1).total_pages
works fine. Curiously,
Post.paginate(:page => 1).total_pages
works fine. I looked at the code on Github ( https://github.com/mislav/will_paginate/blob/master/lib/will_paginate/active_record.rb ) and I can see why paginate works (because it calls limit first... which returns an active record relation, much like scoped does). I have a feeling it has something to do with this code
rel = scoped.extending(RelationMethods)
I guess I don't understand the difference between these the active record relation that limit returns versus scoped.extending(RelationMethods). Any ideas?
This only happens when using the rails_admin gem. It works fine in a fresh Rails 3.1.1 app with will_paginate 3.0.2.
Rails admin is probably doing something to the page method, though I'm not sure what exactly.

Rails association fails on Heroku but works on local box?

Why would I get NoMethodError on my Heroku app when the same code works flawlessly on my local setup?
The error is triggered by this code:
#customer = Customer.find(1)
#customer.responses.create(:offer_id => '1', :digit => '2')
That code works as intended on my local server and in my local Rails console.
However, on Heroku the above code triggers NoMethodError:
NoMethodError (undefined method `responses' for #<Customer:0x7f7bcbee3808>):
The Response model is tied to the Customer model by means of belongs_to :customer
Additionally, I can login to the Heroku console and run this without any problems:
Response.create(:offer_id => '1', :customer_id => '1', :digit => '2')
So if the above works and both versions work fine on my local box, why would the association fail on Heroku?
--
Running Rails 3.0.6 and tested on Heroku Ruby 1.8.7 and Ruby 1.9.2
Databases are identical on Heroku and on my local box.
Usually when something like this doesn't work it indicates you're missing a has_many association. You need to define both the belongs_to and has_many sides of the association if you wish to access them both.
By the sounds of it, if it's working on your local machine but not Heroku then it would be because you haven't pushed the changes to the Heroku server and restarted the console there. Please make sure you have pushed the changes and try again.
Marco, I thought about this a bit, and I have a few guesses for you to try. Before you do either of these, restart your app. Sometimes that does miracles.
heroku restart
Ok, now, try in console just
#customer.responses
What does that return? I assume it should be []. Maybe doing some inspection etc. of that can give us insights here. If you build and associate a response manually can you get it to show up?
Second, your no method error is on responses, not on create, so whatever you type after that probably doesn't matter, BUT, are your offer_id and digit fields integers? If so, try creating them using integers, not strings. PostgreSQL is so fragile compared to MySQL or SQLite, I've had loads of issues that trace back to my unfamiliarity working with Postgre prior to developing on Heroku.
#customer.responses.create(:offer_id=>1,:digit=>3)
That probably doesn't matter but it's worth checking out.
The other thing to check is all your callbacks and validations etc. Is anything failing? It may not seem related but I've had issues before where things acted very weird because of seemingly tiny silent failures in a callback that I had overlooked. I'm sure you're testing as you go, but if you've got shallow test coverage anywhere on this model you might as well use this bug hunt as a chance to beef it up :)
Sympathies on the error, I don't know if any of this will help, but good luck! Please post if Heroku staff find the issue, I'd be very interested to learn from it!
I think you problem is how you are creating the response:
#customer.responses.create(:offer_id => '1', :digit => '2')
You might want to try this instead.
Response.create(:offer_id => '1', :digit => '2', :customer_id => 1)

Ruby on Rails: How do I get rid of the ActiveRecord:ReadOnlyRecord error?

It's happening on teh lp.save line. Which is weird, because I have the same code else where (slightly different though) for re-sorting the link_pages.
the menu bars and link pages are a has and belongs to many relationship
this is in the menu_bar/destroy method
#menu_bar.link_pages.each do |lp|
lp.sequence = LinkPage::NOT_USED
lp.save
end
also, rails 2.3.8
If you loaded link_pages via an ARel :join query, you can probably get rid of the error by changing :join to :include.
A similar question with a more detailed answer was answered here.
You can also use :readonly => false in your find options.
Look at https://stackoverflow.com/a/960903/327786
It works if you use rails 2.3.15 at least.

AR.to_json Works in Console, Fails in Browser

I have this block of code:
users = Array.new
users << User.find(:all, :conditions => ["email like ?", "%foo%"])
users << User.find(:all, :conditions => ["name like ?", "%bar%"])
users.flatten!
users.uniq!
puts users.to_json :include => [:licenses]
When I run it using script/console, it returns exactly what you would think it should, a JSON representation of the Array of users that I found, flattened, and uniquified. But running that same line of code as part of a search_for_users method, I get this error
TypeError in ControllerName#search_for_users
wrong argument type Hash (expected Data)
and the line referenced is the line with the .to_json call.
It's baffling me because the code is verbatim the same. The only difference is that when I'm running it in the console, I'm entering the conditions manually, but in my method, I'm pulling the query from params[:query]. But, I just tried hardcoding the queries and got the same result, so I don't think that is the problem. If I remove the :include, I don't see the error, but I also don't get the data I want.
Anyone have any idea what the issue might be?
There are a few plugins and gems that can cause .to_json to fail if included in your controller. I believe that the Twitter gem is one of them (ran into a problem with this awhile back).
Do you have "include [anything]" or "require [anything]" in this controller?
If not, I'd suggest temporarily removing any plugins you're using to troubleshoot, etc.
Finally, what happens if you replace that entire controller action with simply:
%w(1 2 3 4 5).to_json
That should help you pin down what is failing.
Whenever code in tests or the console behaves different from production environment (which is a guess... you might be running your site in development mode), this calls for a load order issue. In production environment, all the models and controllers are preloaded, in other environments they are loaded lazily when needed.
Start your console with RAILS_ENV=production ./script/console and see if you can reproduce the error this way.
As cscotta mentioned, there are a couple of gems and librarys, that can interfere with .to_json, first to mention the functionality, that you get when you require 'json'. I personally ran into several issues with that.
Hope this helps
Seb

Resources