New features, Aug-Oct 2009

1 view
Skip to first unread message

Francis Hwang

unread,
Oct 31, 2009, 9:56:48 AM10/31/09
to admin_a...@googlegroups.com
Hey guys,

I'd like to keep you guys abreast of various interface changes & new
features, especially because your input is especially valuable there.
It's pretty easy for me to implement features that make sense for me,
but obviously it'd be good to make them sensible to other people too.

Although I really should be updating the docs, too, this seems to be a
more direct way to do it: For now I'm going to try to write occasional
emails saying new features & feature changes, but not bugfixes. At
some point this won't scale but maybe this'll be useful for now.

So, new features in Aug, Sep, and Oct 2009:

= Supports Rails 2.3.3, 2.3.4 in the tests

= Added per_page to the Index API (Luke Melia)

= More options for specifying select options, for example:
form[:admin_level].input = :select
form[:admin_level].select_choices = %w(normal admin superuser)
form[:admin_level].select_options = {:include_blank => false}

= Added hook for before_render_for_index controller method (Luke Melia)

= Added hooks for hooks for helper methods: link_to_new_in_index?,
link_to_edit_in_index?, link_to_delete_in_index? and
link_to_show_in_index?, which allow suppression of links in the index
view that admin_assistant would otherwise render (Luke Melia)

= Referer handling from indexes with pagination, searches, etc: Now
forms set a field called "origin" which saves the state of the index
that led to that form, and then use that to redirect after the object
is saved. For example, say you're looking at an index search which is
"show me all blog posts with the tag 'ruby', order by publish date".
When you edit one of those blog posts, after you're done you'll be
bounced back to that same index search.

= Comparators for datetime searches work now: You can now say "find
all blog posts published after Oct 1 2009."

= Added the column config option :strftime_format, for example:
admin_assistant_for BlogPost do |a|
a[:published_at].strftime_format = "%b %d, %Y %H:%M:%S"
end

= Added index.cache_total_entries option:
index.cache_total_entries 12.hours
Basically, if you have a very big table, MySQL count queries can be
really expensive. Since getting these counts exactly isn't usually
important, this is an easy way to optimize AA controllers on big tables.

= Added option for disabling Ajax toggles of boolean fields in index:
index[:live].ajax_toggle = false

= Better handling of validations, has_many errors, and
[column]_from_form controller methods
Okay, this one's a doozy. Inside admin_assistant, when you do a form
post, it collects a hash-like parameters object and assigns it to the
record, with a standard invocation like:

blog_post.attributes = params[:blog_post]

And it's nice to be able to set associations with this call, too. For
example, let's say blog_post has_many tags, if params[:blog_post]
[:tags] is an array of Tag objects, then ActiveRecord will handle the
assignment.

blog_post.attributes = {:tags => [#<Tag id: 1...>, #<Tag id: 2..>,
#<Tag id: 3..>]}

So, to enable that, you can have, say, a simple text field called
"tags" in the form, and then a tags_from_form method on the controller
that turns that text into an array of Tag objects.

def tags_from_form(tags_string)
tags_strings.split(/\s+/).map { |tag_str|
Tag.find_by_tag(tag_str) || Tag.create(:tag => tag_str)
}
end

admin_assistant will take what this method returns, and assign it to
params[:blog_post][:tags].

Okay, so far so good. But part of the problem is: What if one of the
tags is being created, and has an invalid tag string? Where does the
validation fail?

Turns out it's not a validation in this case, it's some different sort
of exception that you don't normally get to catch. Basically, this
isn't the sort of thing you usually do using #attributes=, and if you
were writing your own code (i.e. not using a lib like admin_assistant)
you'd handle it beforehand in some other special case.

Anyway, my fix was to make it so you can add errors to an errors
object in that same method:

def tags_from_form(tags_string, errors)
tags = tags_strings.split(/\s+/).map { |tag_str|
Tag.find_by_tag(tag_str) || Tag.create(:tag => tag_str)
}
if tags.any? { |t| !t.valid? }
errors.add(:tags, "contains an invalid tag string")
end
tags
end

This is a little wierd for a few reasons, not least of that you're not
explicitly returning the errors object, just mutating it and trusting
that the calling function is holding on to the same reference. But it
works for now. Thoughts are welcome, though, I feel like this is a
pretty unusual way to use ActiveRecord.

= Added #before_validation and #validate hooks on the controller

= Added hook for [column]_value helper methods, which can get called
during form generation for virtual columns

= Added :text_area option for virtual columns, i.e.:
form[:virtual_text].input = :text_area

= If you've defined #name_for_admin_assistant on your model, and that
model is the target of a belongs-to association, the method will be
used in form selects affecting that association

Hope that's of interest. I'm planning, btw, to do these monthly going
forward.

Francis Hwang
http://fhwang.net/



Luke Melia

unread,
Oct 31, 2009, 10:35:56 AM10/31/09
to admin_a...@googlegroups.com
Good summary, Francis. Definitely helpful.

Cheers,
Luke
> --
>
> You received this message because you are subscribed to the Google
> Groups "admin_assistant" group.
> To post to this group, send email to admin_a...@googlegroups.com.
> To unsubscribe from this group, send email to admin_assista...@googlegroups.com
> .
> For more options, visit this group at http://groups.google.com/group/admin_assistant?hl=en
> .
>
>

--
Luke Melia
lu...@lukemelia.com
http://www.lukemelia.com/

Reply all
Reply to author
Forward
0 new messages