Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reader / predicate returning different values for boolean field #17415

Closed
thiagogsr opened this issue Oct 28, 2014 · 25 comments
Closed

Reader / predicate returning different values for boolean field #17415

thiagogsr opened this issue Oct 28, 2014 · 25 comments

Comments

@thiagogsr
Copy link

[33] pry(main)> UserTask.find(13511).task.counselor
  UserTask Load (1.9ms)  SELECT  "user_tasks".* FROM "user_tasks"  WHERE "user_tasks"."id" = $1 LIMIT 1  [["id", 13511]]
  TaskItem Load (0.7ms)  SELECT  "task_items".* FROM "task_items"  WHERE "task_items"."id" = $1 LIMIT 1  [["id", 241]]
=> false
[34] pry(main)> UserTask.find(13511).task.counselor?
  UserTask Load (0.9ms)  SELECT  "user_tasks".* FROM "user_tasks"  WHERE "user_tasks"."id" = $1 LIMIT 1  [["id", 13511]]
  TaskItem Load (1.0ms)  SELECT  "task_items".* FROM "task_items"  WHERE "task_items"."id" = $1 LIMIT 1  [["id", 241]]
=> true
[6] pry(main)> UserTask.find(13511).task.id
  UserTask Load (1.0ms)  SELECT  "user_tasks".* FROM "user_tasks"  WHERE "user_tasks"."id" = $1 LIMIT 1  [["id", 13511]]
  TaskItem Load (1.0ms)  SELECT  "task_items".* FROM "task_items"  WHERE "task_items"."id" = $1 LIMIT 1  [["id", 241]]
=> 241
[7] pry(main)> TaskItem.find(241).counselor?
  TaskItem Load (1.1ms)  SELECT  "task_items".* FROM "task_items"  WHERE "task_items"."id" = $1 LIMIT 1  [["id", 241]]
=> true
[8] pry(main)> TaskItem.find(241).counselor
  TaskItem Load (0.9ms)  SELECT  "task_items".* FROM "task_items"  WHERE "task_items"."id" = $1 LIMIT 1  [["id", 241]]
=> false
  • The value on database is false
  • The field is boolean
  • Rails version: 4.1.6
  • Ruby version: ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]
  • PostgreSQL: 9.3

Is it a bug?

@thiagogsr thiagogsr changed the title Is there a bug on boolean method? Reader / predicate returning different values for boolean field Oct 28, 2014
@thiagogsr
Copy link
Author

This method should be so:

test 'predicate method' do
    assert_equal false, @klass.setting?
    @klass.setting = 1
    assert_equal true, @klass.setting?
  end

or

test 'predicate method' do
    @klass.setting = 0
    assert_equal false, @klass.setting?
    @klass.setting = 1
    assert_equal true, @klass.setting?
  end

On first way is @klass.setting false or nil?

@sgrif
Copy link
Contributor

sgrif commented Oct 28, 2014

This is the expected behavior. The predicate checks for emptiness, not truthiness. Please see the documentation. http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods.html#method-i-attribute_present-3F

@sgrif sgrif closed this as completed Oct 28, 2014
@thiagogsr
Copy link
Author

Yep @sgrif, but others fields have other behaviors

[21] pry(main)> TaskItem.find(241).ancestor
  TaskItem Load (1.1ms)  SELECT  "task_items".* FROM "task_items"  WHERE "task_items"."id" = $1 LIMIT 1  [["id", 241]]
=> false
[22] pry(main)> TaskItem.find(241).ancestor?
  TaskItem Load (0.8ms)  SELECT  "task_items".* FROM "task_items"  WHERE "task_items"."id" = $1 LIMIT 1  [["id", 241]]
=> false
  • The value on database is false
  • The field is boolean

@sgrif
Copy link
Contributor

sgrif commented Oct 28, 2014

Your pry output is making it difficult to understand your problem. Can you please provide an executable test case using this as a template? https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_master.rb

@rafaelfranca
Copy link
Member

Something very weird is going on. The expected behaviour is to return false for false values. See https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/query.rb#L15.

@sgrif
Copy link
Contributor

sgrif commented Oct 28, 2014

Whoops, you are correct I got the suffix mixed up.

@kuldeepaggarwal
Copy link
Contributor

Everything is working fine, here is the gist.

Ruby version: ruby 2.1.4p265 (2014-10-27 revision 48166) [x86_64-darwin13.0]
PostgreSQL: 9.3.2

@thiagogsr
Copy link
Author

@kuldeepaggarwal This problem happened in one field, the reason I don't know. Other boolean fields works!!

@guilhermeFranco
Copy link

This could be happening because you may have an enum that defines a value with the same name as the boolean field in your table.

Since enum values results in predicate methods, you're getting the false value because your object doesn't have that enum "type" assigned to it. The question is: In case we have a field with the same name as a enum value, what should be the correct behavior ? Ask the database field or the enum ?

@thiagogsr
Copy link
Author

@guilhermeFranco is right. I miss the enum declaration with the same name as the boolean field. BTW, shouldn't the FW inform us? enum task_type: [ :junior, :counselor, :senior ]

@rafaelfranca
Copy link
Member

@thiagogsr it does it but for methods already defined by the framework. User defined methods don't give any warning.

@thiagogsr
Copy link
Author

@rafaelfranca I asked because the FW raises a fatal error when I try to use a enum item with same name of any relationship

example:

class User < ActiveRecord::Base
  enum role: [ :admin, :parent, :manager ]
  belongs_to :parent
end

@thiagogsr
Copy link
Author

Test with the problem

@kuldeepaggarwal
Copy link
Contributor

@thiagogsr You have a boolean field as well for counselor, so rails will create 2 methods counselor?, one by boolean field and one by enum.

@kuldeepaggarwal
Copy link
Contributor

I think Rails behaviour is correct in this case.

@thiagogsr
Copy link
Author

@kuldeepaggarwal yep, I just suggested an 'stack level too deep' on this case

@prathamesh-sonpatki
Copy link
Member

How about prefixing enum generated methods like enum_parent?

@guilhermeFranco
Copy link

@prathamesh-sonpatki I would prefer a combination of the enum name and its value. Given the following model:

class User < ActiveRecord::Base
  enum role: [ :admin, :parent, :manager ]
  belongs_to :parent
end

The enum value verification could be:

user.role_admin?

@prathamesh-sonpatki
Copy link
Member

Awesome. This makes sense 😄

@prathamesh-sonpatki
Copy link
Member

Something like this? prathamesh-sonpatki@c314864

@kuldeepaggarwal
Copy link
Contributor

I think then all methods should be prefixed when created by enum.

@kuldeepaggarwal
Copy link
Contributor

I think we should raise error or give warning in this scenario.

@rails-bot
Copy link

This issue has been automatically marked as stale because it has not been commented on for at least
three months.

The resources of the Rails team are limited, and so we are asking for your help.

If you can still reproduce this error on the 4-2-stable, 4-1-stable branches or on master,
please reply with all of the information you have about it in order to keep the issue open.

Thank you for all your contributions.

@kuldeepaggarwal
Copy link
Contributor

We can close this issue as per the discussion in #17506

@kamipo
Copy link
Member

kamipo commented Jan 15, 2018

Closing this since #19813 has already been merged.

@kamipo kamipo closed this as completed Jan 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants