who generates SQL with LIMIT 100 for populating drop-down select lists?

153 views
Skip to first unread message

Montgomery Kosma

unread,
May 21, 2009, 7:29:19 PM5/21/09
to Hobo Users
Thanks to everyone for all the help, things are moving ahead much more
smoothly for me this evening.

Already dipping its toes in the production environment, the team as
now defined 217 employees in the app. The oddity is that I'm getting
precisely 101 options in an employee select (generated by a belongs-to
association). In the html, there's one <option value=""> for "None"
followed by <option value=... for the first 100 employees, in alpha
order as required by my set_default_order tag.

Now, it looks like the SQL being generated to populate the drop-down
is the culprit, as my console window shows:

SELECT * FROM 'employees' LIMIT 100

Where's this 100 coming from -- hobo? rails? More important, how do I
work around it?



Montgomery Kosma

unread,
May 22, 2009, 12:11:57 AM5/22/09
to Hobo Users
found it! appears to be hardwired, non-parametric constraint built
into vendor/plugins/hobo/hobo/taglibs/rapid_forms.dryml. Any
suggestions how to fix this? Based on browsing a ton of source
looking for this, seems like limit probably ought to be set equal to
the count of records... or at very least turned into an option.

<def tag="select-one" attrs="include-none, blank-message, options,
sort"><%
raise HoboError.new("Not allowed to edit #{this_field}") if !
attributes[:disabled] && !can_edit?

blank_message ||= "(No #{this_type.name.to_s.titleize})"

options ||= begin
conditions = ActiveRecord::Associations::BelongsToAssociation.new
(this_parent, this_field_reflection).conditions
this_field_reflection.klass.all(:conditions => conditions, :limit
=> 100).select {|x| can_view?(x)}
end

select_options = options.map { |x| [x.to_s, x.id ] }
select_options = select_options.sort if sort
select_options.insert(0, [blank_message, ""]) if include_none ||
(this.nil? && include_none != false)
attributes = add_classes(attributes, "input", "belongs_to",
type_and_field)
-%>
<select name="#{param_name_for_this(true)}" merge-
attrs="&attributes.except :name">
<%= options_for_select(select_options, this ? this.id : "") %>
</select>
</def>

Montgomery Kosma

unread,
May 22, 2009, 1:59:06 AM5/22/09
to Hobo Users
Trying to work around the LIMIT 100 issue by using <name-one>, likely
a better practice in this situation anyway. However, I'm getting this
routing error as soon as I start typing in the autocomplete field:

Processing ApplicationController#index (for 127.0.0.1 at 2009-05-22
01:10:16) [GET]
Parameters: {"query"=>"gr"}
ActionController::RoutingError (No route matches "/thiss/
complete_employee_name" with {:method=>:get}):

Here's my source - checked against older postings here plus the
Controllers section of the manual and the Agility tutorial - unable to
find any material differences from what should work. Only things I
don't understand right off is the "thiss" in the route and the
collection=find_instance line (but seems unlikely that relates to the
routing error).

class CollectionController < ApplicationController
hobo_model_controller
auto_actions :all
autocomplete :employee_name do
collection = find_instance
hobo_completions :name, Employee
end
end

and

<extend tag="form" for="Collection">
<old-form merge>
<field-list: fields="employee, project, name, full_path">
<employee-view:>
<name-one complete-target="&@collection"
completer="employee_name" />
</employee-view:>
</field-list:>
</old-form>
</extend>

Bryan Larsen

unread,
May 22, 2009, 11:09:44 AM5/22/09
to hobo...@googlegroups.com
> Based on browsing a ton of source
> looking for this, seems like limit probably ought to be set equal to
> the count of records... or at very least turned into an option.
>

If you open a bug, I can certainly parameterize it for you. Or if
you parameterize it and send me a patch, I'll apply it.

Bryan

Bryan Larsen

unread,
May 22, 2009, 11:18:48 AM5/22/09
to hobo...@googlegroups.com
Are you defining @collection anywhere? It's not a magic variable, it
has to be defined in your controller. In the agility tutorial,
@project is defined in the show method. The route for the completer
is reflected from complete-target and completer.

cheers,
Bryan

Tom Locke

unread,
May 22, 2009, 11:53:29 AM5/22/09
to Hobo Users
The reason for the limit 100 was to stop hobo generating impossibly
massive queries sometimes with the auto generated app and existing
databases. Select menus with hundreds of thousands of rows in them,
crashing your whole machine, stuff like that. The idea was to limit it
to a number that was way higher than what you would practically need.
I was thinking that anything above about 50 you should be using a
different UI. Then again I'm now thinking that people do use select
menus for choosing countries, and I think there are about 200 of those
if you include them all, so maybe 100 was too low.

So it was just a safety net. I'm not really sure there's a good reason
to parameterize it is there? When would you use that? (e.g. if we
raise the limit). Then again hard wired constants are lame of course
so maybe we should do it anyway : )

Tom

Montgomery Kosma

unread,
May 22, 2009, 2:32:34 PM5/22/09
to Hobo Users
Hard-wired (and undocumented!) constraints are kind of lame, yes. I
see 4 possibilites:

1. increase hard-wired limit - easy, but issue may arise again
2. set LIMIT equal to COUNT - but that's probably the same as no limit
3. add and document a parameter - pretty much solves it, and pretty
easy
4. nicest solution, add a "more options..." item after the first 100
which refreshes the drop-down and pulls in the next 100 items. Sounds
hard.

Tom Locke

unread,
May 22, 2009, 2:39:03 PM5/22/09
to hobo...@googlegroups.com
Yeah agreed. We should go with 3.

T

Montgomery Kosma

unread,
May 22, 2009, 4:17:48 PM5/22/09
to Hobo Users
Bryan - @collection looks magical to me -- I don't define it, but
debugger (thanks again for that tip!) shows @collection == current
collection object (edit) or blank collection object (new).

Further testing shows that the Employee autocomplete code works
perfectly on an Edit Collection -- the routing error occurs only when
you type in the field on a New Collection page:

Processing ApplicationController#index (for 127.0.0.1 at 2009-05-22
16:06:47) [GET]
Parameters: {"query"=>"ab"}

ActionController::RoutingError (No route matches "/thiss/
complete_employee_name" with {:method=>:get}):

Rendering rescues/layout (not_found)

Montgomery Kosma

unread,
May 22, 2009, 4:26:22 PM5/22/09
to Hobo Users
added ticket #424 on this. Not trying to do it myself for fear of
generating more questions here and generating more "where the hell's
the application?" inquiries from my team. Thanks, guys.

Montgomery Kosma

unread,
May 26, 2009, 10:30:52 PM5/26/09
to Hobo Users
I have narrowed this down a little bit, perhaps. Still looks like --
for a reason I cannot determine -- the routing is not being generated
correctly for autocomplete on a New page:

The dryml code for autocomplete in the Edit page is generating this
route, which works fine as a standalone in the browser:
http://localhost:3000/collections/complete_custodian_name?query=and&id=1

For the working (edit controller) situation, here's what the log
output shows about the routing:

Processing CollectionsController#edit (for 127.0.0.1 at 2009-05-26
20:35:26) [GET]
Parameters: {"id"=>"1-archive-pst"}

... and when keys are typed in the autocomplete field:
Processing CollectionsController#complete_custodian_name (for
127.0.0.1 at 2009-05-26 20:35:38) [GET]
Parameters: {"id"=>"1", "query"=>"a"}

Now, from the New Collection page, here's the development.log output.
Best clue may be that this is processing ApplicationController#index
-- not sure how or why it's getting there. Maybe because there is no
current object -- i.e., the current id is nil? Not sure why
complete_custodian_name needs an id as a parameter anyway....

Processing CollectionsController#new (for 127.0.0.1 at 2009-05-26
20:41:43) [GET]
...
Processing ApplicationController#index (for 127.0.0.1 at 2009-05-26
20:41:57) [GET]
Parameters: {"query"=>"and"}

ActionController::RoutingError (No route matches "/thiss/
complete_custodian_name" with {:method=>:get}):


so I spend the last hour or so trying to read model_router.rb and
model_controller.rb, but I'm afraid it's beyond my current level of
expertise to parse that source. Too many layers, and I don't know
where to begin.

Help!

d@Ve

unread,
Jun 7, 2012, 1:09:21 PM6/7/12
to hobo...@googlegroups.com
three years on, and i am encountering the same issue when using auto-complete on a new document:

ActionController::RoutingError (No route matches "/thiss/complete_user_name")

any resolution? ~daVe

Owen

unread,
Jun 7, 2012, 2:16:14 PM6/7/12
to hobo...@googlegroups.com
Yes, we should definitely squash this one permanently. : -) 

Bryan?

Bryan Larsen

unread,
Jun 7, 2012, 2:37:18 PM6/7/12
to hobo...@googlegroups.com
Montgomery's email was about a problem with select-one. The "limit"
attribute has existed on select-one for quite some time now to fix his
problem.

Your problem is with name-one. It appears that you need to explicitly
specify the complete-target attribute. If you provide more context I
can probably help you further.

Bryan
> --
> You received this message because you are subscribed to the Google Groups
> "Hobo Users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/hobousers/-/3BzO9GWAlNcJ.
> To post to this group, send email to hobo...@googlegroups.com.
> To unsubscribe from this group, send email to
> hobousers+...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/hobousers?hl=en.

David Mason Hill

unread,
Jun 7, 2012, 4:30:26 PM6/7/12
to hobo...@googlegroups.com
here's what i've got (noting that this same call to <name-one> works for my edit-page for this same assignment model):

<edit-page>
  <form:>
    <field-list: fields="hours_spent, minutes_spent, assignee, assignor">
...
      <assignee-view:>
        <name-one complete-target="&@assignment" completer="user_name"/>
      </assignee-view:>        
...
    </field-list:>
  </form:>
</edit-page>

<new-page>
  <form:>
    <field-list: fields="assignor, assignee, assigned_type, assigned, hours_spent, minutes_spent">
...
      <assignee-view:>
        <name-one complete-target="&@assignment" completer="user_name"/>
      </assignee-view:>        
...
    </field-list:>
  </form:>
</new-page>

class AssignmentsController < ApplicationController
  hobo_model_controller
  auto_actions :all

  autocomplete :user_name do
    hobo_completions :name_with_email_address, User, :query_scope => [:first_name_contains, :last_name_contains] 
  end
...
end

class Assignment < ActiveRecord::Base
  hobo_model # Don't put anything above this

  fields do
    hours_spent       :integer, :default => 0#, :options => [0,1,2,3,4,5,6,7,8,9]
    minutes_spent     :integer, :default => 0
    timestamps
  end
  
  # remove from live-search results
  set_search_columns nil

  # fields set automatically based on context

  def name
  end

  def type
    assigned_type
  end

  # default sort
  default_scope :order => 'updated_at desc'

  # --- Associations --- #
  belongs_to :assignor, :class_name => "User", :creator => true
  belongs_to :assignee, :class_name => "User"
  belongs_to :assigned, :polymorphic => true
...
end

class User < ActiveRecord::Base

  hobo_user_model # Don't put anything above this

  fields do
    # name          :string, :required #, :login => true
    first_name    :string, :required
    last_name     :string, :required
    email_address :email_address, :unique, :login => true, :case_sensitive => false
    administrator :boolean, :default => false
    timestamps
  end
...
  def name
    first_name.to_s + ' ' + last_name.to_s 
  end

  # necessary for autocomplete where user has similar or same name as another
  # and thus uniqueness of user determined by email address
  def name_with_email_address
    first_name.to_s + ' ' + last_name.to_s  + ' (' + email_address.to_s + ')' 
  end

  # allow autocomplete to find by name when name is a generated field (see above) 
  def self.find_by_name(name)
    names = name.split(' ')
    (0..(names.length-2)).inject(nil) do |result, n|
      result ||= self.find_by_first_name_and_last_name(names[0..n].join(' '), names[1..(n+1)].join(' '))
    end
  end
...
  # default sort EVERYWHERE!
  default_scope :order => 'last_name, first_name'
  
  # --- Associations --- #
  has_many :assignments
...
end

perusing this group, i continue to see this same issue pop up, so any insight is much appreciated! ~daVe

Bryan Larsen

unread,
Jun 7, 2012, 4:40:38 PM6/7/12
to hobo...@googlegroups.com
Have you tried using complete-target="&Assignment"? on the new page,
@assignment doesn't have an id.

Are you using Hobo 1.3 or Hobo 1.4? The javascript for name-one is
completely different in 1.4.

cheers,
Bryan

d@Ve

unread,
Jun 7, 2012, 4:55:33 PM6/7/12
to hobo...@googlegroups.com
doh! that was it, bryan. thanks much:)

btw, we are on hobo 1.3, anticipating the 1.4 release. we've started investigating 1.4 but have run into quite a few upgrade path issues: will this be one of them, or will our legacy <name-one> calls remain operational as-is?

Bryan Larsen

unread,
Jun 7, 2012, 5:03:53 PM6/7/12
to hobo...@googlegroups.com
name-one and several of the other more complex widgets were built on
top of script.aculo.us. One of the major goals of 1.4 was getting rid
of prototype.js & script.aculo.us, so this necessarily means that the
javascript for many of these widgets has changed substantially.

In many cases this is an improvement because jQuery & jQuery-UI are
much better maintained, but I'm sure that I will have introduced new
bugs in the rewrite. The earlier you try the beta the earlier we can
fix any bugs that affect you. :)

In this case it probably wouldn't have mattered whether you were using
1.3 and 1.4, the code causing your issue is in DRYML and is the same
in both versions. I haven't dug deep enough to figure out whether
your issue is a bug in code or in documentation. Please open a
lighthouse ticket referencing this thread.

thanks,
Bryan
> --
> You received this message because you are subscribed to the Google Groups
> "Hobo Users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/hobousers/-/QMOr51Qhw6YJ.
Reply all
Reply to author
Forward
0 new messages