Forum: Ruby on Rails Validating a boolean non-database addition to a model

Ea712fa65258a359b36d3d4e6a71cdbd?d=identicon&s=25 Asa Romberger (Guest)
on 2014-06-08 03:18
(Received via mailing list)
I have a model with a boolean variable in the database and one added by
attr_accessor:

In the model:

  attr_accessor :attrvalue

  validates(:dbvalue, inclusion: { in: [true, false], message: "%{value}
is
not a valid response"} )

  validates(:attrvalue, inclusion: { in: [true, false], message:
"%{value}
is not a valid response"} )

In the view:

    <%= form_for(@user) do |f| %>

      <%= f.select :dbvalue, {'' => nil, 'Yes' => true, 'No' => false},
{},  { :class => 'span1' } %>

      <%= f.select :attrvalue, {'' => nil, 'Yes' => true, 'No' =>
false},
{},  { :class => 'span1' } %>

    <% end %>

The dbvalue works, the attrvalue does not work and always throws the
message attrvalue is not a valid response.

I assume that attrvalue is not a boolean. Can I force it to be a
boolean?
Alternately, is there another way to handle it?
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2014-06-08 13:24
(Received via mailing list)
On Sunday, June 8, 2014 2:17:08 AM UTC+1, Asa Romberger wrote:

>   attr_accessor :attrvalue

> The dbvalue works, the attrvalue does not work and always throws the message
attrvalue is not a valid response.
>
> I assume that attrvalue is not a boolean. Can I force it to be a boolean?
Alternately, is there another way to handle it?

Forms always submit strings, so the value that ends up in your model is
the string "true" rather than he boolean true. For the dbvalue the
accessors activerecord provides know that the corresponding column is a
boolean column so they convert the string to the appropriate boolean
(see
https://github.com/rails/rails/blob/master/activer...
for some of the typecasting )

You could either choose to do the same (ie provide your own setter
method that does this conversion) or choose to mangle the parameters in
the controller. I find both options a little icky - the model is the one
that knows which attribute should be of each type but it feels a little
dirty that a detail of the way in which http form posts are handled
(values are always strings) ends up in your model.

Fred.
45eedc761b47f81c6b95c965980574e1?d=identicon&s=25 James Kwame (Guest)
on 2014-06-08 15:42
(Received via mailing list)
What exactly are you trying to achieve with this approach, why do you
need
to have the second attr not in the database and validated?

To answer your question, yes you can force it to be a boolean, by
creating
your own accessor methods

Instead of attr_accessor :attrvalue
  def attrvalue
    @value
  end

  def attrvalue=(new_value)
      if new_value == "true"
         @value = true
      else
         @value = false
      end
  end
Ea712fa65258a359b36d3d4e6a71cdbd?d=identicon&s=25 Asa Romberger (Guest)
on 2014-06-08 23:42
(Received via mailing list)
The second attr is a transient only used when the user signs up for an
account, so I did not want to save it it in the database.

I now have in the model:

attr_accessor :completed_cfdym
def completed_cfdym
  @completed_cfdym
end
def completed_cfdym=(var)
  if var = 'true'
    @completed_cfdym = 'true'
  else
    if var = 'false'
      @completed_cfdym = 'false'
    else
      @completed_cfdym = ''
    end
  end
end
validates(:completed_cfdym, inclusion: { in: [true, false], message:
"%{value} is not a valid response"} )

The '' is because I do want force the user to answer.

And the view:

      <%= f.label :completed_cfdym, "Have you already completed 'A
Conversation for the Difference You Make in Life?", class: 'span5'  %>
      <%= f.select :completed_cfdym, {'' => nil, 'Yes' => true, 'No' =>
false}, {}, { :class => 'span1' } %>

This still fails with:
Completed cfdym is not a valid response

It also does not preserve the value that I set when it displays the
error
and goes back to the '' => 'nil' setting
7f959297e473789a12397cc20cd3996c?d=identicon&s=25 dasibre (Guest)
on 2014-06-09 17:14
(Received via mailing list)
You should remove the quotes from your boolean values.
   @completed_cfdym = 'true' should be    @completed_cfdym = true this
should solve the Completed cfdym is not a valid response error.
To preserve form values after failure you have to use params[:fieldname]

<%= f.select :completed_cfdym, params[:completed_dfdym],{'' => nil,
'Yes'
=> true, 'No' => false}, {}, { :class => 'span1' } %>
Then use render in your controller on form submit failure.

    attr_accessor :
Ea712fa65258a359b36d3d4e6a71cdbd?d=identicon&s=25 Asa Romberger (Guest)
on 2014-06-09 21:35
(Received via mailing list)
Removing the '' on true and false made no difference.

I also tried the addition of params[:completed_cfdym], both with and
without the :completed_cfdym, and both give me a rails error.
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2014-06-10 12:14
(Received via mailing list)
On Monday, June 9, 2014 8:34:19 PM UTC+1, Asa Romberger wrote:
>
> Removing the '' on true and false made no difference.
>
> You're comparing with = rather than ==

Fred
Ea712fa65258a359b36d3d4e6a71cdbd?d=identicon&s=25 Asa Romberger (Guest)
on 2014-06-11 03:47
(Received via mailing list)
I now have:

model:

        attr_accessor :completed_cfdym
        def completed_cfdym
          @completed_cfdym
        end
        def completed_cfdym=(var)
          if var == 'true'
            @completed_cfdym = true
          else
            if var == 'false'
              @completed_cfdym = false
            else
              @completed_cfdym = ''
            end
          end
        end
        validates(:completed_cfdym, inclusion: { in: [true, false],
message: "%{value} is not a valid response"} )

view:

      <%= f.label :completed_cfdym, "Have you already completed 'A
Conversation for the Difference You Make in Life?", class: 'span5'  %>
      <%= f.select :completed_cfdym, {'' => nil, 'Yes' => true, 'No' =>
false}, {}, { :class => 'span1' } %>

I get the diagnostic:
* Completed cfdym is not a valid response

Is there a construct, like the %{value} that I can use to print out the
response?
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.