HoboFields Decimal :required ordering?

25 views
Skip to first unread message

JezC

unread,
Jan 3, 2012, 6:00:34 AM1/3/12
to Hobo Users
The manual doesn't state that order is important -
http://cookbook.hobocentral.net/manual/hobo_fields/api - but it
appears that :required sometimes has to immediately follow the type,
and sometimes doesn't. For example when I try a hobo migration
including this field:

percentage :decimal, :scale => 1, :precision => 3, :required

it creates an error message about expecting a "\n" in tASSOC. But:

percentage :decimal, :required, :scale => 1, :precision => 3

works (creates a migration). However:

value enum_string(:first, :second, :third), :required

seems to work. So :required isn't always required immediately after
the column type.

I suspect this is a bug rather than a documentation oversight, because
the order of declaration is sensitive to the types involved?

I've also got a case where a nested set of :accessible models causes a
complete rails crash through what looks like a null pointer
dereference? Should I be posting these problems here? Is it helpful if
I make a test case and share it on GitHub?

It feels ungrateful to keep posting problems, but I'm sufficiently new
to both Hobo and Rails that I'm finding more problems than solutions :
(

Cheers, JeremyC.

Tomoaki Hayasaka

unread,
Jan 3, 2012, 7:01:28 AM1/3/12
to hobo...@googlegroups.com
<<EOS
Field declaration is handled by method_missing(), that means the
declaration must be a valid Ruby method call.

Remember that Ruby has a parser feature that you can omit braces if
the last argument of a method call is a Hash. Rails and Hobo use
that feature for "named options".
EOS

def enum_string(*args)
"type enum_string #{args.inspect}"
end

def decl(type, *args)
puts "@@@ decl(): type = #{type}"
options = args.extract_options!
args.each_with_index { |val, i| puts " args[#{i}] = #{val.inspect}" }
options.each { |key, val| puts " options[#{key.inspect}] = #{val.inspect}" }
end

# decl :decimal, :scale => 1, :precision => 3, :required # 1. syntax error, unexpected '\n', expecting tASSOC
decl :decimal, { :scale => 1, :precision => 3 }, :required # 2. no syntax error, but won't work as expected
decl :decimal, :required, { :scale => 1, :precision => 3 } # 3. works
decl :decimal, :required, :scale => 1, :precision => 3 # 4. works, same as 3.
decl enum_string(:first, :second, :third), :required, {} # 5. works
decl enum_string(:first, :second, :third), :required # 6. works, same as 5.

JezC

unread,
Jan 3, 2012, 10:12:57 AM1/3/12
to Hobo Users
Hi - I was expecting the handling to be more along the lines of
":required is a new value in the hash".

I'll probably stick to a validation that requires presence, until I
work out when a hash is in use and when it isn't :)

To be honest, I never even thought of scale and precision as being
named options in a Hash. They usually get treated in tutorials as just
a list of stuff you add to the end of a declaration, like :default
and :null. More reading, then. :)

Newbies, eh? How do you go about working this out? I mean, I started
(for migrations) with documents like http://guides.rubyonerails.org/migrations.html
- there's no hint there of a named option hash. Just a lot of things
that can get appended to a declaration. There's not even a reference
to some other resource that provides more detail, is there? Even stuff
like http://api.rubyonrails.org/classes/ActiveRecord.ConnectionAdapaters/TableDefinition.htl
doesn't mention that the :scale and :precision have to come last
because they are in a named option hash.

Thanks for the detailed help and explanation! I'm now both wiser and
more confused, at the same time. What document set have I missed
reading that would let me know that :decimal has a named option hash?
I'm clearly missing something quite important.

Cheers, JeremyC.

On Jan 3, 12:01 pm, Tomoaki Hayasaka <hayas...@pfsl.mech.tohoku.ac.jp>
wrote:

Tomoaki Hayasaka

unread,
Jan 3, 2012, 2:22:19 PM1/3/12
to hobo...@googlegroups.com
> Hi - I was expecting the handling to be more along the lines
> of ":required is a new value in the hash".

I would agree that it is really confusing for programmers who has no
Rails background, though I don't know if I can call it a documentation
bug. If you know it, it's obvious, but if not, it's not. Here are
some hints:

- .rb files are Ruby files. DSL fragments such as field
declarations of Hobo Fields, assocations (has_many, etc.) and
validations (validates_presence_of, etc) are all syntactically
valid Ruby expressions.

- Rails uses "hash as a named option" feature throughout the API.
A `:key => something` argument is probably a named option and you
should place it as the last argument of the method call. Simple
`:key` argument (without associated value) is not a hash and it
won't be a named option. There are some exceptions such as
`button_to(name, options = {}, html_options = {})` helper where
two hashes are expected and you must sometimes explicitly place
surrounding braces to solve ambiguities.

> Even stuff like
> http://api.rubyonrails.org/classes/ActiveRecord.ConnectionAdapaters/TableDefinition.htl
> doesn't mention that the :scale and :precision have to come
> last because they are in a named option hash.

The method signature `column(name, type, options = {})` and the
descriptions in
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html
tell you that `name` should be provided first, `type` should be
second, and options hash may be followed and the options may contain
`:scale => something`.

-----
Tomoaki Hayasaka <haya...@pfsl.mech.tohoku.ac.jp>

kevinpfromnm

unread,
Jan 3, 2012, 5:33:13 PM1/3/12
to hobo...@googlegroups.com
I believe the problem is that the plain :required syntax doesn't mix with the hash style options the way you're thinking.  Try with :required => true for when you need required along with hash style options.

JezC

unread,
Jan 6, 2012, 6:06:02 AM1/6/12
to Hobo Users
Thats extremely helpful - thanks.

I can see where my expectations are wrong now. I like @kevinpfromnm's
suggestion to use "required" as if it is an option has component; used
like that it is more "natural" for users, I suspect.

I'd like to suggest that a bit of a documentation tweak would help -
us newbies do rely on tutorials and can be disheartened and put off
when extending what we're shown doesn't work. One example showing how
to mix :required with option hashes should be a good pointer?

Thanks so much for your generous help. Much appreciated.

On Jan 3, 7:22 pm, Tomoaki Hayasaka <hayas...@pfsl.mech.tohoku.ac.jp>
wrote:
> > Hi - I was expecting the handling to be more along the lines
> > of ":required is a new value in the hash".
>
> I would agree that it is really confusing for programmers who has no
> Rails background, though I don't know if I can call it a documentation
> bug.  If you know it, it's obvious, but if not, it's not.  Here are
> some hints:
>
>   - .rb files are Ruby files.  DSL fragments such as field
>     declarations of Hobo Fields, assocations (has_many, etc.) and
>     validations (validates_presence_of, etc) are all syntactically
>     valid Ruby expressions.
>
>   - Rails uses "hash as a named option" feature throughout the API.
>     A `:key => something` argument is probably a named option and you
>     should place it as the last argument of the method call.  Simple
>     `:key` argument (without associated value) is not a hash and it
>     won't be a named option.  There are some exceptions such as
>     `button_to(name, options = {}, html_options = {})` helper where
>     two hashes are expected and you must sometimes explicitly place
>     surrounding braces to solve ambiguities.
>
> > Even stuff like
> >http://api.rubyonrails.org/classes/ActiveRecord.ConnectionAdapaters/T...
> > doesn't mention that the :scale and :precision have to come
> > last because they are in a named option hash.
>
> The method signature `column(name, type, options = {})` and the
> descriptions in
>  http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Ta...
> tell you that `name` should be provided first, `type` should be
> second, and options hash may be followed and the options may contain
> `:scale => something`.
>
> -----
> Tomoaki Hayasaka <hayas...@pfsl.mech.tohoku.ac.jp>
Reply all
Reply to author
Forward
0 new messages