开发者

Value stored in boolean column as false is evaluated as true by Rails?

开发者 https://www.devze.com 2023-03-16 23:57 出处:网络
I\'m having a lot of trouble getting a simple true/false to evaluate properly in Rails. I have this in a helper:

I'm having a lot of trouble getting a simple true/false to evaluate properly in Rails. I have this in a helper:

 def should_we_ask_to_subscribe?
    if @user.email.blank?
      true
    elsif @user.subscriber == false
      true
    else
      false
    end
  end

I test for blank because the user object is created by omniauth and sometimes, as with Twitter, I don't get an email. After the authorization is created, the user is directed to update their profile and add an email. If there's no email, I make sure to present the option to subscribe because they can't be subscribed. This is the view:

<% if should_we_ask_to_subscribe?  %>

    <div class="field"> 
      <%= f.check_box :subscriber %>
      <%= f.label :subscriber, "It's okay to send me the occassional email. I know I can unsubscribe at any time." %>
    </div>

  <% else %>

     <div class="field">
        You're subscribed to our email list.<br /> 
        <%= f.check_box :unsubscribe %>
        <%= f.label :unsubscribe, "Please unsubscribe me." %>
      </div>

  <% end %>

However, even when the subscribe boolean is set to f -- say a user has entered an email, but not subscribed (or unsubscribed, which is the only way the boolean would be f) should_we_ask_to_subscribe? still evaluates to false. I've tried various permuations but am just not getting it.

Update

Okay, so it's clear that the database is storing the boolean value as false, but rails is interpreting it as true and I can't really get why. Following advice below with inspect, the log shows @user.subscriber = true even though in the console and in the database I get subscriber: false for that particular user.

Second Update

So I've written some unit tests and they all pass. In my logs, I notice the code is doing the following:

(0.4ms)  UPDATE "users" SET "subscriber" = 'f', "updated_at" = '2011-07-05 13:40:58.178186' WHERE "users"."id" = 47

and this is the code, in a method in my model, that does that:

self.update_attribute(:subscriber, false)   

When I look at the database, both through an SQLite view and the console, I see an f and u.subscriber => false, respectively. But, when I use logger.info "@user.subscriber = #{@user.subscriber.inspect}" to see how the view helper is interpreting it, I get: @user.subscriber = true in the log. So, I'm assuming the problem is with how I set false since it seems rails is interpreting any value in the subscriber column as true (except in the console开发者_C百科, where it seems to be saying its false?).


This is a good candidate for a unit test that will exercise your model and determine if the correct behavior is implemented. For instance:

@user = User.create(...)

assert @user.email.blank?
assert !@user.subscriber?

assert_equal true, @user.should_we_ask_to_subscribe?

@user.email = 'test@example.email'

assert_equal false, @user.should_we_ask_to_subscribe?

@user.unsubscribe = true

assert_equal true, @user.should_we_ask_to_subscribe?

As a note, if you're dealing with variables that are interpreted as either true or false, you don't need to be so formal about comparing values to false specifically. A simple refactoring would look like this:

def should_we_ask_to_subscribe?
  # Show subscription option if no email has been provided.
  return true if @user.email.blank?

  # Otherwise ask to subscribe if not a subscriber
  !@user.subscriber?
end


Diagnose whether the value of subscriber is not nil (which is a false equivalent) or whether it is not any other value.

Put this line in the should_we_ask_to_subscribe function:

logger.info "@user.subscriber = #{@user.subscriber.inspect}"

Is your subscriber attribute declared as boolean? The checkbox would send a value of "0" (a string), which will evaluate to true in ruby, but usually is magically translated to 'false', but only for boolean attributes.


I am currious to see in what way the subscriber field information is saved in your database.

Could you raise @user.subscriber within your should_we_ask_to_subscribe? function please?

  • Add this at the top of your function : raise @user.subscriber.inspect
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号