Vacation
Did i mention that i’m still on vacation? More random rants and stuff next year 🙂 Have a great 2009!
Did i mention that i’m still on vacation? More random rants and stuff next year 🙂 Have a great 2009!
Again, the MySQL ruby gem totally annyoed me trying to install it on a fresh Mac OS X 10.5.5 install and MySQL 5.0.67.
This time the following command brought it to life:
sudo env ARCHFLAGS="-arch i386" gem install mysql -- \ --with-mysql-dir=/usr/local/mysql --with-mysql-lib=/usr/local/mysql/lib \ --with-mysql-include=/usr/local/mysql/include |
Thanks to a bitter software engineer.
Lately i’ve been rambling and ranting a lot on twitter about the Grails framework.
To my surprise, many other developers actually read this tweets and helped me out on some problems. Thanks a lot gals and guys, i really appreciate that. Me rambling isn’t meant to be personal at any time, i guess you know how easily one gets frustrated with too less time and too much stuff to do.
Anyway, here are some shortcuts that could eventually be helpful. I’m gonna add more to this list the next days:
Took me a little digging through the source code, but i came up with the following idea:
import org.springframework.transaction.support.TransactionSynchronizationManager; class SecurityFilters { def sessionFactory def filters = { login(controller:'*', action:'*') { before = { // get your user id somewhere def whatsoeveruserId = 0 def sessionHolder = TransactionSynchronizationManager.getResource(sessionFactory); sessionHolder.getSession().enableFilter("filterByOwner").setParameter("currentUserId", whatsoeveruserId); } } } } |
I want to have some kind of rowlevel security through a Hibernate filter. Through dependency injection i get hold of the sessionFactory and through the TA Manager, i get the current session on which i can enable my filter.
Doing this in a Grails filter, i can combine this with some kinda login mechanism and i’m good to go.
To me it’s a bad idea using blacklisting on data binding as i can and will forget attributes that must not be updated through a webform.
With Marc i found the following solution:
bindData(entity, params, entity.properties.collect{it.key} - ['foo', 'bar']) |
That way only attributes foo and bar gets updated.
Anyway, with Grails 1.1 this won’t be necessary anymore as Graeme anonced.
Graeme was so kind to comment on this: This feature is already in 1.0.x, i just didn’t find it, have a look at the docu at The Web Layer.
bindData(entity, params, [include:['foo', 'bar']]) |
Updates on 2008/12/9
The grails reference has a handy example for adding custom errors to domain classes, have a look here. This works quite well except that all other errors from databinding are mysteriously gone.
For me, the following steps worked to update a user (change some persistent attributes and the transient attributes password and passwordConfirmation):
bindData(anwender, params, [include:['name', 'vorname', 'password', 'passwordConfirmation']]) if(params.password != "" && params.password == params.passwordConfirmation) anwender.hashPassword() // As alway, never ever store plaintext passwords ;) else if(params.password != "") { anwender.validate() // IMPORTANT without that step, possible other errors from bindData vanished anwender.errors.rejectValue('password', 'user.anwender.passwords_doesnotmatch') } |
Afterwords, hasErrors() show all errors, i.a. non nullable fields and the like.
I somewhat used to hibernate and come along very well with it, even though i’m actually a SQL fan. I guess if my inside into the Spring Framework would be a little bit deeper, some areas wouldn’t be hard to understand.
On the other hand i think that Grails does a great job for J2EE based development and it should do so even more. As always, there is the law of leaky abstractions, but the whole butload of stuff that is the J2EE stack should be abstracted away.
Updates on 2009/2/6
I use hibernate validator in my domain classes (that i created outside of rails as hibernate annotated classes) and i got
java.lang.NoSuchMethodError: org.hibernate.event.PreInsertEvent.getSource()Lorg/hibernate/engine/SessionImplementor |
on every insert and update. Hibernate validator 3.0.0.GA is incompatible with the Hibernate version in Grails 1.1-beta3. Problem was gone after upgrading validator to 3.1.0.GA.
Some other stuff:
Ok, i see this was done on purpose: “Plugins are now stored in your USER_HOME directory. You will need to re-install your plugins or run” (from the beta2 release note). Not a good decision making this a default imho. I like having my apps pinned to specific plugins.
If you followed the instructions here and used the method named PDF::Writer (Austin Ziegler), you we’re out of luck when Rails 2.1 appeared.
With Rails 2.2.2 once again the rendering mechanism seems to have changed big time and my previous post on how to make the pdf/writer gem work with a custom template handler doesn’t work anymore.
With the help of Josh Peek i was able to fix this. He gave me the following code to enable a rpdf template handler with pdf-writer:
module ActionView # :nodoc: require 'pdf/writer' class PDFRender < ActionView::TemplateHandler PAPER = 'A4' include ApplicationHelper include ActionView::Helpers::TranslationHelper include ActionView::Helpers::AssetTagHelper include ActionView::Helpers::TextHelper include ActionView::Helpers::TagHelper include ActionView::Helpers::UrlHelper def self.call(template) "ActionView::PDFRender.new(self).render(template, local_assigns)" end def initialize(action_view) @action_view = action_view end # Render the PDF def render(template, local_assigns = {}) @action_view.controller.headers["Content-Type"] ||= 'application/pdf' # Retrieve controller variables @action_view.controller.instance_variables.each do |v| instance_variable_set(v, @action_view.controller.instance_variable_get(v)) end pdf = ::PDF::Writer.new( :paper => PAPER ) pdf.compressed = true if RAILS_ENV != 'development' eval template.source, nil, '' pdf.render end end end ActionView::Template.register_template_handler 'rpdf', ActionView::PDFRender |
Just drop this under config/initializers and you’re fine.
Not just for ruby but also the corresponding formats for
Java
public static final SimpleDateFormat RFC3339_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); |
and for Oracle
SELECT to_timestamp_tz('1979-21-09T06:54:00+01:00','YYYY-MM-DD"T"HH24:MI:SSTZH:TZM') FROM dual / |
Oracle