09:37
<mrgreenfur>
Is there a simple way to add a computed column to a model? I'd like to show averages of a related model without re-querying each time it's requested
10:37
<sigurd->
Hello, does sequel work with ruby 1.9.3? I'm getting ArgumentError: argument out of range (Sequel::InvalidValue) from time.rb:202:in `make_time' when calling .first on a result
11:02
<sigurd->
I tried installing the latest version from github, but I'm still getting the same error
11:04
<leucos>
sigurd-: may be this comes from your db adaptor.? Sequel is doing great for me with 1.9.3. Have a traceback ?
11:05
<sigurd->
yeah, here: http://pastie.org/3264041
11:05
<Caesium>
is it a mysql datetime which is set to zero or something?
11:06
<sigurd->
yes, that it posible, I have some values I'm not using
11:06
<sigurd->
it worked just fine earlier though
11:07
<Caesium>
could be 1.9.3 is stricter about zero dates
11:08
<sigurd->
yeah, I'll try to add some dates just to see
11:14
<jeremyevans>
mrgreenfur: Usually what I'd do in your case is add a dataset method that uses select_append to add an additional column to return.
11:15
<jeremyevans>
sigurd-: If you are using invalid dates/times in MySQL, you probably want to set DB.convert_invalid_date_time = nil
11:16
<leucos>
When Chuck Norris has an ORM problem, he always asks jeremyevans
11:17
<sigurd->
ok, thanks. But I'm gonna try fiksing it by inserting the dates I'm actually going to store there first
11:17
<jeremyevans>
sigurd-: Certainly working with valid dates is preferable :)
11:23
<sigurd->
It's working fine now. Thanks for the help. I think the problem was that I/Rails might have changed the table to NOT NULL on the datetimes
11:25
<jeremyevans>
sigurd-: And I know with certain MySQL configs (maybe even the default), that means if you attempt to insert a NULL value, it will automatically change it to a bogus value
11:25
<sigurd->
yeah, it listed it as 0000-00-00 00:00:00
11:26
<mrgreenfur>
jeremyevans: thanks, i understand the dataset method part, but is there a way to use a subquery in select_append? I'd like to get a computed value from a related table
11:26
<jeremyevans>
sigurd-: I require more sane behavior from the databases I use in production, which is why I use postgres :)
11:27
<jeremyevans>
mrgreenfur: Sure: select_append(DB[:table].select{sum(foo)}.where(:bar=>'baz'))
11:27
<jeremyevans>
mrgreenfur: with an .as(:column) at the end so you get a consistent column alias
11:29
<sigurd->
jeremyevans: Yeah, I've used postgres in classes, but I'm used to mysql so I've been using it for personal projects
11:30
<jeremyevans>
sigurd-: It's never to late to switch. Postgres is better in almost every way.
11:30
<sigurd->
I'll remember that next time :)
11:30
<mrgreenfur>
jeremyevans: thanks!
11:41
<mrgreenfur>
jeremyevans: is there a place to put that in the model definition? Maybe when defining the on_to_many?
11:43
<jeremyevans>
mrgreenfur: def_dataset_method/dataset_module can be called anywhere in the model definition
11:47
<mrgreenfur>
hrm, this is getting complicated. How bad of an idea is it to save computed values in a table and updated them in code? :)
11:56
<jeremyevans>
mrgreenfur: Not bad at all, if you do it correctly in a database trigger
11:56
<jeremyevans>
mrgreenfur: Doing it in an after hook in a model is much less desireable
11:57
<mrgreenfur>
jeremyevans: Ahh, awesome. I was afraid I would violate a normal-form or somesuch. I'll drop a trigger in when the related table gets an insert/delete.
11:58
<jeremyevans>
Well, it might actually violate a normal form, but denormalization for performance reasons is considered good sense my most DBAs
11:58
<mrgreenfur>
i can live with that. Browseing the whole database and having it do a bunch of calculations on each element is killing me.
11:59
<mrgreenfur>
err whole table
11:59
<mrgreenfur>
plus, i've never used a trigger, this'll be fun
11:59
<jeremyevans>
mrgreenfur: Are you doing something simple like a counter or a total field?
12:00
<mrgreenfur>
jeremyevans: an average of ratings for an associated model that saves individual ratings
12:03
<jeremyevans>
mrgreenfur: What database are you using?
12:05
<mrgreenfur>
jeremyevans: mysql; I've got a page that shows the elements sorted by their average rating and it was probably poorly coded (sorting in ruby and not in mysql)
12:07
<jeremyevans>
mrgreenfur: Basically, you'll want an after insert/update/delete trigger on the associated model table that updates the current model table with the average
12:07
<jeremyevans>
mrgreenfur: It'll make inserts/updates/deletes more expensive, but if your access pattern is mostly read only, that's probably not a big deal
12:07
<mrgreenfur>
jeremyevans: yeah! then I can use .order(:average_rating) and it'll be much faster
12:19
<mrgreenfur>
jeremyevans: this works great. Thanks much for your help!
13:48
<sts>
hello folks. is there a way to override a models setter methods to eg. encrypt a password before saving a dataset?
13:53
<Caesium>
you could override the = operation?
13:53
<Caesium>
def password=(password)
13:53
<Caesium>
in the model?
13:54
<Caesium>
hm probably best to call the argument something else though ;)
13:58
<jeremyevans>
Caesium: Just define the method and call super
13:59
<sts>
Caesium: ok and how do i assign the new value? Is super(new_value) still the way to go?
14:00
<Caesium>
jeremyevans: so it'd be something like self[:password] = dostuffto arg \n super
14:00
<Caesium>
or just super(dostuffto arg) ?
14:05
<jeremyevans>
Caesium: super is preferable
14:06
<jeremyevans>
Caesium: self[:password] = dostuff will work in most cases, but if you have a plugin that overrides password=, then things will probably break
14:39
<GitHub190>
[sequel] xaviershay opened issue #427: Generating impossible queries. https://github.com/jeremyevans/sequel/issues/427: http://git.io/v-ZYBg
15:34
<msch>
is there a way to have a common base class that inherits from Sequel::Model where I can put some common stuff?
15:35
<msch>
problem is, sequel tries to read from a table for this "abstract" class
15:42
<jeremyevans>
msch: BaseClass = Class.new(Sequel::Model)
15:42
<jeremyevans>
msch: but you can just add methods to Sequel::Model itself
15:43
<jeremyevans>
msch: If all of your classes inherit from the same base class, I'd just modify Sequel::Model itself
15:43
<msch>
jeremyevans: well it's not all :)
15:43
<jeremyevans>
If only some do, then the base class approach works. Either that, or put it in a module and include that module in all the classes
15:44
<msch>
so does Class.new approach skip the "inherited" callback, or how does this work?
15:44
<jeremyevans>
msch: The inherited stuff looks for the name of the class. If the class has no name (and anonymous classes don't), then it doesn't associate it with a dataset
15:57
<msch>
hm... i tried overwriting MySubclass.new to include some Module sometimes, and it gets called for .new and for .create, but not when I'm fetching via e.g. .all
15:58
<jeremyevans>
msch: That's expected. You probably want an after_initialize hook instead
15:59
<msch>
jeremyevans: it's weird but i need to change the instantiated model's class at runtime
15:59
<msch>
jeremyevans: because if i include a Module in each new object ruby will soon run out of memory
16:00
<jeremyevans>
msch: Can you paste what you are doing. Because you shouldn't need to be including a module with every object
16:01
<msch>
jeremyevans: my entities can have tags and certain tags should mix in code
16:01
<msch>
jeremyevans: e.g. Person is tagged with Evil, then overwrite lend_money
16:02
<jeremyevans>
msch: Personally, I tend to use conditionals for that, but I suppose if you have a lot of different tags, that can get out of hand
16:02
<msch>
jeremyevans: yep we've got like 20 tags.
16:03
<jeremyevans>
msch: I don't think it should run ruby out of memory though. You should just be doing an extend(Evil) inside after_initialize
16:03
<msch>
ok that sounds nice
16:03
<jeremyevans>
msch: Basically, put each tagged behavior in a separate module, and extend the classes in after initialize based on the tags
16:03
<jeremyevans>
extend the instances I mean
16:07
<msch>
jeremyevans: yeah that sounds good. i was just afraid that ruby would create a new shadow class each time that never gets GCed
16:08
<jeremyevans>
msch: Nope. It won't be great in terms of performance, but it shouldn't break the GC
16:11
<msch>
wouldn't post_load be a better place to put it?
16:11
<jeremyevans>
msch: No, that's only called in a specific case
16:11
<msch>
thanks a lot by the way!
16:22
<chris__>
The after_initialize hook in my model blows up if I define it as private, but the other hooks work just fine this way. Is this a bug?
16:23
<jeremyevans>
chris__: hooks should be public methods
16:23
<jeremyevans>
chris__: that's how Sequel defines them
16:23
<jeremyevans>
chris__: The reason it fails is that Sequel now uses allocate instead of initialize for objects retreived from the database
16:25
<chris__>
jeremyevans: Hmm, ok. It makes more sense to me for hooks to be private, since it feels like other classes shouldn't be calling them, but if the implementation requires it I guess it's not a big deal.
17:49
<GitHub73>
[sequel] jeremyevans pushed 1 new commit to master: http://git.io/5VhFbw
17:49
<GitHub73>
[sequel/master] Change IN/NOT IN handling of empty arrays (Fixes #427) - Jeremy Evans