My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement
I recently made a proof-of-concept to get MS Word to edit documents in a Rails app and save them back to the server, using Devise for authentication. It wasn't straightforward, so I thought I'd mention the steps I took to get it done.

I used Rails 3.2.12 with rack_dav providing the WebDAV functionality. There's also dav4rack which was based on rack_dav, and adds a few features.

I started with rack_dav, and had all of the kinks worked out except for the authentication, when I noticed dav4rack included authentication. So I switched to dav4rack, but I had some trouble with it, so I switched back to rack_dav because I feared I'd get into another day-or-two-long yak shaving session.

You might check it out though, and see if it works just as well.

Anyway, here's the basis of what I did.

1. Add the gem to my Gemfile (and run bundle install):

gem 'rack_dav'

2. Mount it in my routes.rb, wrapped with basic authentication:

    webdav = RackDAV::Handler.new(:root => 'private/docs/', :resource_class => LockableFileResource)
    webdav_with_auth = Rack::Auth::Basic.new(webdav) do |username, password|
      user = User.find_for_authentication(:email => username)
      user && user.valid_password?(password)
    end    
    mount webdav_with_auth, at: "/webdav_docs"

3. Create my lockable file resource, which doesn't really do any locking (since this was just a PoC), so you probably want to fix that: More...

Hey! Why don't you make your life easier and subscribe to the full post or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!



Last week at the Houston Ruby User Group I made a presentation called "The Website's Slow" Tips and Tools for Identifying Performance Bottlenecks.

Image of the first slide in the presentation

That link is to the slides and notes on each slide mentioning a little about what I said.

Basically I went through a couple of different classes of performance issues you're likely to see on the server side of things, what tools you might use to make finding the issue easier, how you can interpret some of the data, and even a suggestion here or there about what to do to resolve common issues I've seen.

Let me know what you think! (Or, if you have any questions, feel free to ask!)


Here's a 35 minute recording of the presentation which I gave to houstonrb on February 21, 2012. It is a practice run I did before the live presentation, so you won't get the discussion, but hopefully you'll find it useful anyway.

How to avoid becoming a formerly-employed Rails developer standing in line at the OOP Kitchen from Sammy Larbi on Vimeo.



You can find the slides here: Slides for the Rails OOP presentation

There is also reference to a project whose purpose is to eventually be a full-scale demonstration of the techniques: Project for the Rails OOP presentation

Let me know what you think in the comments below.

Updated to use HTML5 player at Vimeo.


You know when you see code like this:

class CompulsionsController < ApplicationController
    # ... standard actions above here
    def update
      if params[:obsessions].include?(ObsessionsTypes[:murdering_small_animals])
        handle_sociopathic_obsessions
        redirect_to socio_path and return
      elsif params[:obsessions]
        handle_normal_obsessions
        redirect_to standard_obsessions_path and return
      end
     
      # normal update for compulsions
      @compulsion = Compulsions.find(params[:id])
     
      if(@compulsion.update_attributes(params[:compulsion]))
      # ... remainder of the standard actions below here
  end

and the phrase "WTF were they thinking?" runs through your mind? More...


plupload-rails3 is now available as a gem, and it now works on Rails 3.1.

Automated tests are still virtually non-existent, which was a result of me not having a good idea for a strategy on how to test it in any useful manner. But after briefly bouncing ideas off of Jesse Wolgamott last night at the HRUG meeting, I think that will improve.

If you have an issue or improvement, don't be afraid to let me know.

PS: I'd like to give a little thank you to David Radcliffe, who prompted me to make these changes.


Frequent changes and deprecations to technology you rely upon cause dependencies to break if you want to upgrade. In many cases, you'll find yourself hacking through someone else's code to try to fix it, because a new version has yet to be release (and probably never will). That can be a chore.

I get embarrassed when something I've recommended falls prey to this cycle. Backwards compatibility is one way to deal with the issue, but in the Rails world, few seem worried about it. It doesn't bother me that code and interface quality is a high priority, but it does cause extra work.

There's a trick you can use to help isolate the pain, decrease the work involved in keeping your app up to date, and improve your code in general. You've probably heard of it, but you might not be using it to help you out in this area: encapsulation.

More...


I'm working on a website analytics tool, and in pursuit of that goal, I wanted to POST some data from a series of websites to the one that's doing the tracking. If you've tried to do that before, you've run afoul of the same origin policy, as I did, so you'll need to specify how your application handles Cross-Origin Resource Sharing.

I won't go into all the details about why that is the case - for that you can read the Wikipedia links above. Instead, I'm going to show a short example of how I handled this in my Rails 3 app.

First, you need to specify a route that will handle an HTTP OPTIONS method request.

# config/routes.rb
  resources :web_hits, :only=>[:create]
  match '/web_hits', :controller => 'web_hits', :action => 'options', :constraints => {:method => 'OPTIONS'}
  

More...


Yesterday I got sick of typing rake test and rake db:migrate and being told
You have already activated rake 0.9.2, but your Gemfile requires rake 0.8.7. Consider using bundle exec.
I know you should always run bundle exec, but my unconscious memory has not caught up with my conscious one on that aspect, so I always forget to run rake under bundle exec.

So I wondered aloud on twitter if I could just alias rake to bundle exec rake, but confine that setting to specific directories (with bash being my shell).

Turns out, it is possible with the help of another tool that Calvin Spealman pointed me towards: capn.

More...


You can split an input on a specific string to get the same field to autocomplete multiple times. One example where you might want to do this is in the case of tags: You have a field that should contain multiple tags, and you want to do an autocomplete after every comma + space (', ').

It's not documented in the rails3-jquery-autocomplete README, but all you need to do is use the 'data-delimiter' attribute like this:

<%= f.label :category_tags %>
<%= f.autocomplete_field :category_tags, autocomplete_category_tag_title_library_assets_path, 'data-delimiter'=>', ' %>

Hopefully this helps you save a little time by allowing you to skip reading the implementation to find this detail.


Here is the beginning of a Rails 3 plugin for plupload

Plupload lets you upload multiple files at a time and even allows drag and drop from the local file system into the browser (with Firefox and Safari).

This plugin tries to make its integration with Rails 3 very simple.

To install (from inside your project's directory): More...


What's a better name for this function, and how do you better accomplish the same task? Gist at github: remote_function_with_container_and_id_from_javascript.rb


Rails Rumble has nothing on this.

Of course, you could just click the edit button in your database management studio of choice and achieve the same functionality.

SELECT DISTINCT 'script/generate scaffold ' + t.name + ' ' + column_names
FROM sys.tables t
CROSS APPLY (
    SELECT c.name + 
           case when max_length > 255 then ':text' else ':string' end + ' '
    FROM sys.columns c
    WHERE c.object_id = t.object_id
    ORDER BY c.column_id
    FOR XML PATH('') ) dummy_identifier ( column_names )


A similar discovery was made in the 1930's. One important difference to note is that, since my program does not simulate the input on it's output program, I am able to achieve speeds that are logarithmically faster than what Turing could accomplish.



I've spent some time recently building a tool that makes my life a bit easier.

Finishing up a simple Rails log filter. Tired of tracking down sessions for support requests and it takes too long even for support kids.

I've browsed plenty of Rails log analyzers that help me find performance bottlenecks and potential improvements. But what I really need is a faster way to filter my logs to trace user sessions for support purposes. Maybe it's just me, but I've got apps where users report problems that make no sense, where their data gets lost, and who can't tell me what they did. Add to that the fact that I've got the same app running on dozens of different sites, and you can see why performance analyzers aren't what I'm looking for to solve my problem.

Because of that, I need a solution that lets me filter down and search parameters to figure out what a particular user was doing on a certain date. Hence, Ties. More...


This post might be better titled, "How (and how not) to help yourself when Google doesn't have the answer: A whirlwind tour through Rails' source" if only I wasn't too lazy to change the max length of the database field for titles to my blog entries.

Google sometimes seems as if it has the sum of all human knowledge within the confines of its search index. It might even be the case that it does. Even if you prefer to think that's true, there may come a time when humanity does not yet have the knowledge you are seeking.

How often is that going to happen? Surely someone has run up against the problems I'm going to have, right? That hasn't been the case for me the last couple of months.

I may be the only developer writing Rails apps on MacOSX to be deployed to the world on Windows where SQL Server 2008 is the backend to a Sharepoint install used by internal staff to drive the data. I'm not so presumptious to think I'm a beautiful and unique snowflake, but I wasn't finding any answers. More...


Code in Views and Code in the Wrong Place are two of the top 20 Rails development No-No's that came up in Chad Fowler's straw poll on Twitter about poor practices in Ruby on Rails.



Domain code in controllers and views isn't a problem that's limited to Rails, of course. It's a problem everywhere, and one you generally need to remain vigilant about. Rails doesn't make it easy by making it easy - it's much too easy to do the wrong thing.

You've got the view open and think, "I need to get a list of Widgets."

More...


This is a story about my journey as a programmer, the major highs and lows I've had along the way, and how this post came to be. It's not about how ecstasy made me a better programmer, so I apologize if that's why you came.

In any case, we'll start at the end, jump to the beginning, and move along back to today. It's long, but I hope the read is as rewarding as the write.

A while back, Reg Braithwaite challenged programing bloggers with three posts he'd love to read (and one that he wouldn't). I loved the idea so much that I've been thinking about all my experiences as a programmer off and on for the last several months, trying to find the links between what I learned from certain languages that made me a better programmer in others, and how they made me better overall. That's how this post came to be. More...


Last night John Lam posted about Steve Yegge's port of Rails to JavaScript (Running on Rhino, "JavaScript for Java" on the JVM," not in the browser).

Sounds interesting.

Update: Steve responds and explains how it's not much to get hyped up about.


This one refers to the 40+ minute presentation by Obie Fernandez on Agile DSL Development in Ruby. (Is InfoQ not one of the greatest resources ever?)

You should really view the video for better details, but I'll give a little rundown of the talk here. Obie starts out talking about how you should design the language first with the domain expert, constantly refining it until it is good - and only then should you worry about implementing it (this is about the same procedure you'd follow if you were building an expert system as well). That's where most of the Agility comes into play. More...


Sean Corfield responded in some depth to "Is Rails easy?", and explained what I wish I could have when I said (awkwardly, rereading it now) "I think my cat probably couldn't [code a Rails app]."

Sean makes it quite clear (as did Venkat's original post) that it isn't that using a framework, technology, or tool in general is easy or hard (although, you can certainly do things to make it easier or harder to use). In many cases, what it does for you is easy to begin with - in the case of Rails, it is stuff you do all the time that amounts to time-wasting, repetitive, boring busy-work. Rather, the right way to look at them is that they are tools that make you more productive, and it takes a while to learn to use them.

If you go into them thinking they are easy, you're likely to be disappointed and drop a tool that can really save you time before you learn to use it. And that could be tragic, if you value your time.


This morning I was reading an announcement for another Rails-based conference (Not RailsConf, and I didn't think to save the email, so I'm not sure what I could link to here), and I thought to myself, "Self, isn't Rails supposed to be easy? How is there possibly enough to talk about that justifies having so much conference exposure?"

If it takes that long to explain it, surely it isn't easy.

Well, Rails is pretty simple - as someone noted on Ruby-Talk the other day, it doesn't take long to see that the magic of Rails is just its excellent use of Ruby, and even its strongest points aren't particularly hard if you see that it can be done (which I admit, is probably true about most things).

But as Venkat (co-author of Practices of an Agile Developer, among other books) pointed out today (completely by coincidence), it's not so simple that the brainless can do it. As he noted, in his move from C++ to Java he became more productive, but no one "would say that Java makes an ignorant programmer more productive." In fact, he asks, "Can your cat code my Rails app?"

I think my cat probably couldn't do it. But, can yours? =)


Peter Bell's presentation on LightWire generated some comments I found very interesting and thought provoking. (Perhaps Peter is not simply into application generation, but comment generation as well.)

The one I find most interesting is brought up by several people whose opinions I value - Joe Rinehart, Sean Corfield, Jared Rypka-Hauer, and others during and after the presentation. That is: what is the distinction between code and data, and specifically, is XML code or data (assuming there is a difference)? More...


As I'm getting into little details about the generation cfrails is doing, I had a couple of questions I thought the community could provide some insight on better than my own experiences regarding lists.

One of the great things about generating this stuff is that you can have for free all the bells and whistles that used to take a long time to do. In particular, you can have sorting on columns automatically generated, as well as pagination.

So question 1 is: given that you can have sorting for free, would you rather automatically sort on every column, and specify any columns you did not want to sort on, or would you prefer to not have sorting placed automatically, but just specify which columns to sort on?

And question 2: Given that more and more people are on broadband, is it time to up the 10-record limit on results? I find it annoying to have to reload all the time, and if given the option, I normally up the results/page to 50 or 100. What do you think, would you make the default number of results/page higher (and how high would you take it?), or would you cater to the lowest common denominator?


There are a couple of drawbacks (or some incompleteness) to scaffolding being truly useful. The one that seems to be most often cited is that normally (at least in Ruby on Rails, which seems to have popularized it) it looks like crap (it is only scaffolding though). Of course, most who make that complaint also recognize that it is only a starting point from which you should build.

Django has been generating (what I feel is) production-quality "admin" scaffolding since I first heard about it. It looks clean and professional. Compare that to the bare-bones you get by default in Rails, and you're left wondering, "why didn't they do that?" Well, as it happens, it has been done. In particular, there are at least 4 such products for use with Rails: Rails AutoAdmin (which professes to be "heavily inspired by the Django administration system"), ActiveScaffold (which is just entering RC2 status), Hobo, and Streamlined (whose site is down for me at the moment). More...


It had been a while since I visited InfoQ, but the other day I got one of their mailings in my inbox, and tons of it was relevant to my interests (even more so than normal). Rather than having a separate post for all of it, I decided to combine much of it into this post.

First, this post let me know that Thoughtworks has released CruiseControl.rb, which is good news for Ruby users who also want continuous integration. I've yet to use it, but those guys are a great company and it seems like everything they touch turns to gold. More...


One of the things I've been dreading is getting Rails to work with IIS, although it appears to be getting easier (last time I checked, there was no such "seamless integration"). But eWeek has some good news. They note that core developer on the JRuby project, Charles Nutter
said the JRuby project will announce, possibly as soon as this week, that JRuby supports the popular Ruby on Rails Web development framework. Ruby on Rails is sometimes referred to as RoR or simply Rails.

"We're trying to finish off the last few test cases so we can claim that more than 95 percent of core Rails tests passed across the board," Nutter said.

Moreover, the JRuby team is inviting Rails developers to try out real-world usage of JRuby and help them find any Rails issues the unit tests do not cover, or any remaining failures that are crucial for real applications, Nutter said.

Support for Ruby on Rails is important because "once Rails can run on JVM alongside other Java apps, existing Java shops will have a vector to bringing Rails apps into their organizations. They won't have to toss out the existing investment in servers and software to go with the new kid on the block," Nutter said.
The article also mentions "Microsoft is looking at support for Ruby developers and broader uses of Ruby, including having it run on the CLR."

Both bits of good news for fans of Ruby who want it to play well with Windows and IIS. Not to mention that using JRuby (or NRuby, if it will be called that for .NET) should open up all of those libraries available to Java/.NET developers, which has been considered by some to be one of Ruby's weaker spots.


For those that don't know, cfrails is supposed to be a very light framework for obtaining MVC architecture with little to no effort (aside from putting custom methods where they belong). It works such that any changes to your database tables are reflected immediately throughout the application.

For instance, if you change the order of the columns, the order of those fields in the form is changed. If you change the name of a column or it's data type, the labels for those form fields are changed, and the validations for that column are also changed, along with the format in which it is displayed (for example, a money field displays with the local currency, datetime in the local format, and so forth). I've also been developing a sort-of DSL for it, so configuration can be performed quite easily programmatically (not just through the database), and you can follow DRY to the extreme. Further, some of this includes (and will include) custom data types (right now, there are only a couple of custom data types based on default data types). More...


Regarding some of the problems we had in automating testing for our rails app, I was reminded of another today: how do we test functionality that requires the user to be logged in?

At first, I tried just setting the required session variables manually, in the setup method. Now, I can't see why that didn't work, and I didn't investigate long enough to find out, because Rachana Parmar, one of our team members, had a brilliant idea: why not just go through the login process? So, she wrote a test helper method that we could call that instantiated the user controller and performed the login action. After that, we had no more problems related to needing to log in to the app to test something.

On another note, I want to explain these short, almost useless postings: Part of the idea here is that I want to learn, and I find that when I write something down, I remember it better. And if I forget, I can always look it up when I know "I've seen this before, but I can't remember how we solved it." So, I find them helpful, and my hope is that someone else will too.

As another aside, for the longest time I didn't write down simple solutions like this and the previous one about upgrading functionality only for users with Javascript enabled, but the idea came to me when I read Venkat Subramaniam's and Andy Hunt's Practices of an Agile Developer. It's chock full of great advice, and even though most of it is obvious common sense (or seems that way), I found that I wasn't really doing a lot of the things it suggests. So, I have to give credit where credit is due.


There are plenty out there who think it won't/can't cut it. But, Amazon is using it for Unspun. Check out the best programming languages or the home page (which is not working at the time I write this - so are those people right?).

David Heinemeier Hansson (the creator of Rails) on the Rails blog also mentions "a bunch of other announcements for high-profile companies going Ruby on Rails for various new projects" are forthcoming. Judging by the comments on that post, we have to hope it fairs better than the Unspun announcement.


As I'm finishing up a Ruby on Rails project today, I've been reflecting on some of the issues we had, and what caused them. One glaring one is our lack of automated tests - in the unit (what Rails calls unit, anyway) test and functional test categories.

The "unit" tests - I'm not too concerned about, overall. These tests run against our models, and since most of them simply inherit from ActiveRecord::Base (ActiveRecord is an ORM for Ruby), with some relationships and validation thrown in (both of which taken care of by ActiveRecord). In the few cases we have some real code to test, we've (for the most part) tested it.

What concerns me are the functional tests (these test our controllers). Of course, Rails generates test code for the scaffolds (if you use them), so we started with a nice, passing, suite of tests. But the speed of development in Rails combined with the lack of a convenient way to run tests and the time it takes to run them has caused us to allow our coverage to degrade, pretty severely. It contributed to very few automated tests being written, compared with what we may have done in a Java project, for example.

Of course, there were some tests written, but not near as many as we'd normally like to have. When a small change takes just a couple of seconds to do and and (say, for instance) 30 seconds to run the test, it becomes too easy to just say, "forget it, I'm moving on to the next item on the list." It definitely takes a lot of discipline to maintain high coverage (I don't have any metrics for this project, but trust me, its nowhere near acceptable).

Well that got me thinking about Coldfusion. I notice myself lacking in tests there as well. I'd traditionally write more in Coldfusion that what we did on this Rails project, but almost certainly I'd write less than in an equivalent Java project. And it's not just less because there is less code in a CF or Rails project than in Java - I'm talking more about the percent of code covered by the tests, rather than the raw number. It's because there is no convenient way to run them, and run them quickly.

For Rails development, I'm using RadRails (an Eclipse plugin), so at least I can run the tests within the IDE. But, there is no easy way to run all the tests. I take that back, there is, but for some reason, it always hangs on me at 66%, and refuses to show me any results. I can also use rake (a Ruby make, in a nutshell) to run all the tests via the console, but it becomes very difficult to see which tests are failing and what the message was with any more than a few tests. Couple this with the execution time, and I've left testing for programming the application.

In Coldfusion, it takes quite a while to run the tests period. This is due partly to the limitations of performance in creating CFCs, but also to the fact I'm testing a lot of queries. But at least I can run them pretty conveniently, although it could be a lot better. Now, I've got some ideas to let you run one set of tests, or even one test at a time, and to separate slow tests from fast ones, and choose which ones you want to run. So, look out in the future for this test runner when I'm done with it (it's not going to be super-sweet, but I expect it could save some much-needed time). And then the next thing to go on my mile-long to-do list will be writing a desktop CF server and integrate the unit testing with CFEclipse... (yeah, right - that's going on the bottom of the list).


So, the last couple of weeks I've been hard at work with school stuff, and also we've started a new (well, massively adding on to an existing one) project at work (and now another new one, as of last Wednesday). Because I seem to be so incredibly busy, and the projects need to be done "yesterday" (don't they all?), I built myself a little helper application that should increase my velocity by a ton - no more repetitive busy-work (well, it is greatly reduced anyway).

I've quite unimaginatively called it cfrails, since it was inspired by Ruby on Rails, and you can find it's project page at RIA Forge.

But first, you might want to read Getting Started with cfrails, so you can see how easily 0 lines of real code can create an interface to your database (the only lines are a couple of setup things, and cfcomponent creation).

I'd like to know what you think, so please leave a comment.


I could have sworn I had RadRails and Instant Rails working and was able to develop Ruby on Rails applications several months ago. But, I think I had a funktified setup, as yesterday I couldn't get it to work at all.

So, I went looking for what was wrong, and came across Matt Griffith's screencast about how to get started with Rails (in less than 5 minutes!).

The first thing to do was get InstantRails. I already had it, but I downloaded again just in case I had old versions of everything. Then, I followed his easy directions. I've restated them here, since I'm new to this and easily forget.

  1. Unzip Instant Rails where you want it to reside. I chose C:\InstantRails
  2. Start Instant Rails. Click the "OK" button to let it update the configuration file
  3. If IIS is running (you get port 80 is in use by inetinfo.exe, stop IIS by typing iisreset /stop at the command prompt
  4. Open a Ruby console window through Instant Rails by clicking The "I" button -> Rails Applications -> Open Ruby Console Window
  5. You should be in C:\InstantRails\rails_apps. If you are working on a new application, generate it by using the command: rails <project_name>. Matt called his demo, so the command was "rails demo."
  6. Move to the project directory, C:\InstantRails\rails_apps\demo
  7. Generate a controller: ruby script/generate controller <ControllerName>
  8. Generate a model: ruby script/generate model <ModelName>
  9. Create a migration by editing the file: C:\InstantRails\rails_apps\demo\db\migrate\001_create_posts.rb (assuming your model was called Post
  10. In the self.up method in that file, add the columns (one per line). For instance, t.column :title, :string on the first line, then t.column :body, :text (he is using a blog as an example).
  11. Open the configuration file for the database. This is found in C:\InstantRails\rails_apps\demo\config\database.yml. Basically, you can find the names of the databases you are going to need to create. We'll be doing demo_development.
  12. Start Apache to create the database using php administrator interface to MySQL. You can start Apache by clicking on Apache->Start in Instant Rails. Be sure to unblock it if Windows Security asks.
  13. Click I->Configure->Database (via PhpMyAdmin)
  14. That will open a browser to the admin page. Just type in the name of the database and submit the form. Ours is called demo_development.
  15. Stop Apache (in Instant Rails click Apache->Stop)
  16. Start WEBrick: In C:\InstantRails\rails_apps\demo, type the command: ruby script/server. If Windows asks, unblock it. Take note of the port it will be using.
  17. Set up the controller to have something. Open C:\InstantRails\rails_apps\demo\app\controllers\blog_controller.rb. In the class, type scaffold :post
  18. To create the database, run the migration. In C:\InstantRails\rails_apps\demo type the command: rake db:migrate
  19. Now you can go to http://localhost:3000 (or whatever port it is using). Here you'll see the "Welcome Aboard" page from Rails.
  20. To see your application, go to http://localhost:3000/blog. Play around, have fun.
If you are working on an existing application, obviously you can skip several of those steps (like, every one that involves creating a new application).

Now, I'll see about getting RadRails working in the next few days.



Google
Web CodeOdor.com

Me
Picture of me

Topics
.NET (19)
AI/Machine Learning (14)
Answers To 100 Interview Questions (10)
Bioinformatics (2)
Business (1)
C and Cplusplus (6)
cfrails (22)
ColdFusion (78)
Customer Relations (15)
Databases (3)
DRY (18)
DSLs (11)
Future Tech (5)
Games (5)
Groovy/Grails (8)
Hardware (1)
IDEs (9)
Java (38)
JavaScript (4)
Linux (2)
Lisp (1)
Mac OS (4)
Management (15)
MediaServerX (1)
Miscellany (76)
OOAD (37)
Productivity (11)
Programming (168)
Programming Quotables (9)
Rails (31)
Ruby (67)
Save Your Job (58)
scriptaGulous (4)
Software Development Process (23)
TDD (41)
TDDing xorblog (6)
Tools (5)
Web Development (8)
Windows (1)
With (1)
YAGNI (10)

Resources
Agile Manifesto & Principles
Principles Of OOD
ColdFusion
CFUnit
Ruby
Ruby on Rails
JUnit



RSS 2.0: Full Post | Short Blurb
Subscribe by email:

Delivered by FeedBurner