Active_Admin Undefined Method Error in Production Only - undefined

I've got a User model and a Strengths model. A user has_many strengths, and I'm trying to build an admin panel in Active_Admin for Strengths that displays the User's first_name and email. It works perfectly in development but when I push to Heroku I get this message:
ActionView::Template::Error (undefined method `first_name' for nil:NilClass):
app/admin/strengths.rb:5:in `block (3 levels) in <top (required)>'
This is what I have so far that works in development:
app > admin > strengths.rb
ActiveAdmin.register Strength do
index do
column "Strength ID", :id
column "Name" do |i|
i.user.first_name
end
column "Email" do |i|
i.user.email
end
column :producer
column :versatility
default_actions
end
end
Any ideas why I would get an error in production but not in development?

this may cause becoz u dont have record in Strengths model,
try adding if condition in first_name and last_name column as,
column "Name" do |i|
i.user.first_name if i.user.present?
end
this will avoid error if record is not present.

Related

Using Concat within a Rails Scope

I have a Contact model. It has the attributes: first_name and last_name. The user enters text in a search field with the prompt: Enter the contact's full name. Rails then needs to find all contact records LIKE the name entered.
Here is a picture of the contact records:
-If the user types in "JOE" then rails will return two records (because it is case insensitive)
-If the user types in "joe s" then rails will return two records
-If the user types in "doe" then rails will return one record.
#models/contact.rb
class Contact < ActiveRecord::Base
scope :by_entered_name, -> (full_name){where("CONCAT('first_name',' ','last_name') LIKE ?", full_name)}
end
Generated sql when I run Contact.by_entered_name("joe") in the rails console:
SELECT "contacts".* FROM "contacts" WHERE (CONCAT('first_name',' ','last_name') LIKE 'joe'
I am using mysql in case that detail is important. For this example app however, I am using sqlite, and it is throwing a syntax error. Ultimately what is most important is that I get this to work on mysql.
Update: It was expressed that my question was not clear. My question is:
How do I properly create a query which takes text entered by a user, and finds all contacts whose concatenated first_name and last_name are LIKE that submitted text by the user? I also need it to be case insensitive. My attempted scope above does not appear to work.
There are some quotes in there you don't need. And you need the wildcard % in the parameter. Also, ILIKE is needed to disregard the case with Postgres.
class Contact < ActiveRecord::Base
scope :by_entered_name, -> (full_name){where("CONCAT(first_name,' ',last_name) ILIKE ?", "%#{full_name}%")}
end
SQLite doesn't use the CONCAT function, it uses || as a concatenation operator. Swards' answer will get you going in MySQL.

ActiveRecord not behaving as I expect it

Ruby 2.0
Windows 8.1
Rails 4.1
MySQL2 gem
To avoid an error, I am using the following code to check for an existing payment, prior to creating a new payment record:
payment = {"organization_id" => organization_id,
"date" => row[1],
"amount" => row[2],
"description" => row[3]}
slug = "#{organization_id.to_s}_#{row[1].to_s}_#{row[2].to_s}_#{row[3]})
organization_payment = OrganizationPayment.where(:slug => slug)[0]
if !organization_payment
new_organization_payment = OrganizationPayment.create(payment)
end
Every once in a while, I am getting the following error:
Mysql2::Error at /process_uploaded_payments_data
Duplicate entry 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx' for key 'index_organization_payments_on_slug'
I also have the following in my model:
validates_uniqueness_of :slug
Is there any reason why the entry causing the duplicate error would not have been caught by the code above? Any ideas?
Solution
I am still not certain what caused the problem, but I learned the hard way that validating uniqueness does not really work, if you also have a before_save call in your model that creates the slug in question. The workaround is an exception handler:
begin
new_organization_payment = OrganizationPayment.create(payment)
rescue ActiveRecord::RecordNotUnique
next
end
I don't know if this is your problem but a possible cause of this could be race condition -- when your code is running in a process it can be interrupted right after the if condition before it creates the new record.
Putting a unique constraint on the column in the database is a fine way of dealing with this problem, though. You can catch the exception and deal with it that way. You also don't have to manually check for the duplicity, you can use active record validations; fetching the entire record just to check if it exists is not the best practice anyway. More info:
http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_uniqueness_of

Rails - Model Validations doesn't apply on mysql insert/update command

For the reason, I've used mysql cmd insert into table_name (....) update custom_reports ...and hence I miss out on Model validations
validates_uniqueness_of :name
validates_presence_of :name, :description
How to validate now in rails way? Or, use the mysql way to validate(needs help in this way too)?
Rails validation and other ActiveRecord and ActiveModel magic don't work if you only execute custom SQL command. None of your model classes is even instantized then.
For Mysql (or any sql like DB), you can modify the column attribute to:
Unique (this would validate uniqueness)
Not null (this would validate presence)
I know doing the above with OCI8 and oracle would result in exceptions which I am guessing should be same with ActiveRecord and Mysql, so you should be handling your exceptions correctly
But as #Marek as said you should be relying on Active record and be doing things like
Model.create()
OR
model_instance.save()
If you want to find (and perhaps handle) the entries in your db that are not valid, try the following in the rails console:
ModelName.find_each do |item|
unless item.valid?
puts "Item ##{item.id} is invalid"
# code to fix the problem...
end
end
valid? runs the Validations again, but does not alter the data.

Rails: How to handle existing invalid dates in database?

First, this is directly related to my other question:
How to gracefully handle "Mysql2::Error: Invalid date" in ActiveRecord?
But I still do not want to jump through all the loops of writing migrations which fix dates. That won't be the last table with invalid dates and I need some more generic approach.
So here we go:
I'm using a legacy MySQL database which contains invalid dates, sometimes like 2010-01-00 or 0000-04-25... Rails does not load such records (older versions of Rails did).
I do not want to (and cannot) correct these dates manually or automated. It should be up to the authors of those records to correct these dates. The old system was a PHP application which allowed such annoyances. The Rails application should/will just prevent the user from saving the record until the dates are valid.
The problem does not seem to be within Rails itself, but deeper within an .so library of the rails mysql gem.
So my question is not about how to validate the date or how to insert invalid dates. I don't want to do that and that's covered by numerous answers all over stackoverflow and the rest of the internet. My question is how to READ invalid dates from MySQL that already exist in the database without Rails exploding into 1000 little pieces...
The column type is DATETIME and I'm not sure if casting to string could help because Rails chokes before any ActiveRecord related parsing kicks in.
Here's the exact error and backtrace:
$ rails c
Loading development environment (Rails 3.2.13)
irb(main):001:0> Poll.first
Poll Load (0.5ms) SELECT `polls`.* FROM `polls` LIMIT 1
Mysql2::Error: Invalid date: 2003-00-01 00:00:00
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:216:in `each'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:216:in `to_a'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:216:in `exec_query'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:224:in `select'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/database_statements.rb:18:in `select_all'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/query_cache.rb:63:in `select_all'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/querying.rb:38:in `find_by_sql'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/explain.rb:41:in `logging_query_plan'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/querying.rb:37:in `find_by_sql'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/relation.rb:171:in `exec_queries'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/relation.rb:160:in `to_a'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/explain.rb:34:in `logging_query_plan'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/relation.rb:159:in `to_a'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/relation/finder_methods.rb:380:in `find_first'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/relation/finder_methods.rb:122:in `first'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/querying.rb:5:in `__send__'
from /home/kakra/.gem/ruby/1.8/gems/activerecord-3.2.13/lib/active_record/querying.rb:5:in `first'
from (irb):1
The backtrace remains the same even when I do Poll.first.title so some date should never reach any output routine in IRB and thus should never be parsed. So suggestions to use a value before typecasting would not help.
I think the simplest solution that worked for me was to set in database.yml file cast: false, e.g. for development section
development
<<: *default
adapter: mysql2
(... some other settings ...)
cast: false
try this out
ActiveRecord::AttributeMethods::BeforeTypeCast provides a way to read the value of the attributes before typecasting and deserialization.
http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html

Table 'project_dev.users' doesn't exist

I just created a new table using a Rails migration, then I created a model where I added in its relationships.
I have restarted my console, and the MySQL console shows the table in the project_dev database.
When I try to create a new record in my Ruby console, I get:
Mysql::Error: Table 'project_dev.trace_users' doesn't exist
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/activerecord-3.0.1/lib/act
ive_record/connection_adapters/mysql_adapter.rb:287:in 'query'
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/activerecord-3.0.1/lib/act
ive_record/connection_adapters/mysql_adapter.rb:287:in 'execute'
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/activerecord-3.0.1/lib/act
ive_record/connection_adapters/mysql_adapter.rb:438:in 'columns'
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/activerecord-3.0.1/lib/act
ive_record/base.rb:679:in 'columns'
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/activerecord-3.0.1/lib/act
ive_record/persistence.rb:285:in 'attributes_from_column_definition'
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/activerecord-3.0.1/lib/act
ive_record/locking/optimistic.rb:62:in 'attributes_from_column_definition'
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/activerecord-3.0.1/lib/act
ive_record/base.rb:1396:in 'initialize'
from (irb):2:in 'new'
from (irb):2
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/railties-3.0.1/lib/rails/c
ommands/console.rb:44:in 'start'
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/railties-3.0.1/lib/rails/c
ommands/console.rb:8:in 'start'
from C:/Sanj/Ruby192/lib/ruby/gems/1.9.1/gems/railties-3.0.1/lib/rails/c
ommands.rb:23:in '<top (required)>'
from script/rails:6:in 'require'
from script/rails:6:in '<main>'
It seems I was a little more incompetent yesterday than I'd otherwise like to admit - the migration tables had been created in singular form instead of plural - this led to the table trace_user instead of trace_users.
#Ben - I called the table that because I have a few trace tables in the system recording different kinds of events, and I preferred to have all the trace tables together - IMHO this helps to make the tables easier to understand when trying to comprehend the system as a whole.
You had a User model and then added a Trace model, right? You did everything right, except that since you added has_many users in Trace, you now have to create the association table (through another migration). Consider getting the association direction correct (user has_many traces?) so that the table is user_traces, which to me sounds better.