3

I have models Client and Sessions and a join model ClientSessionAssignment that associates the two. ClientSessionAssignment has one join column score which is defined as decimal type in schema.rb. I'm using has_many with select to preload score values when querying instances of Client as follows:

class Client < ActiveRecord::Base
  has_many :sessions,
    :through => :client_session_assignments,
    :select => 'sessions.*, client_session_assignments.score'
end

Despite score being defined as decimal in the database, when it is accessed this way, Active Record represents it as a string, i.e. Client.first.sessions.first.score.class yields String when I would expect it to yield BigDecimal. Consequently, I have to cast or convert scores obtained this way to BigDecimal before I can perform any calculations on them.

UPDATES

It turns out that only the postgresql database adapter exhibits this strange behaviour. I have filed https://github.com/rails/rails/issues/13044 to track this in the Rails bug tracker on GitHub: full test case is at https://gist.github.com/rcook/7670071.

6
  • What is the output when you remove the :select option in your association declaration and run Client.first.sessions.first.score.class again? Commented Nov 22, 2013 at 16:05
  • Without the :select option, then score is not added to Client.first.sessions.first. Commented Nov 23, 2013 at 16:52
  • Oh right. Try this instead: Client.first.client_session_assignments.first.score.class Commented Nov 23, 2013 at 18:52
  • This returns BigDecimal. Commented Nov 24, 2013 at 2:49
  • What database you are using? and can you post the code in schema where decimal column is declared and can you post any sample app in github, because I tried with rails 3.2.13 and mysql db, its working fine(returns BigDecimal calling through associations) Commented Nov 24, 2013 at 17:29

2 Answers 2

1

Seems like activerecord isn't type casting properly through the association. Try overwriting the accessor method in your join model:

class ClientSessionAssignment < ActiveRecord::Base
  def score
    ActiveRecord::ConnectionAdapters::Column.value_to_decimal super
  end
end

This should return a BigDecimal when you call Client.first.sessions.first.score

Sign up to request clarification or add additional context in comments.

2 Comments

I'll try that tonight. This looks like it'll work around this behaviour. Do you know if this is a bug in Active Record?
Just found out from your question, it might be.
0

This is a bug in Rails 3.2.x:

https://github.com/rails/rails/issues/13044

It's been fixed in Rails 4.0.1.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.