07 Feb, 2007

Published at 06:58PM

Tagged with work, ruby, rails, and programming

This post has 3 comments

Working with transactions in Rails

I’ve been playing around with transactions a little bit, and it seems like it will work nicely for something I need to do at work. But I’m somewhat confused with the model prefix.

For example, I have to read in folders from a directory, parse out the folder name as a generic title for the database, then go into that folder and save all of the sub-folders as a has_many relationship to the parent folder, in the same manner. But I don’t want to save the parent folder or any of its sub-folders if an exception is thrown. The content has to be tracked, so I need the information in the database.

So what I’m doing is allowing an admin to view the available content (folders in a directory that aren’t yet in the database) versus the active content (what’s already in the database). I’m allowing the content to be toggled (activated/deactivated) based on these two methods:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# call to 'activate' a course
def load_course
  @course = Course.new
  @course.title = params[:title] if params[:title]
  Course.transaction do
    @course.save!
    read_directory(@course.folder_title).each do |f|
      lo = LearningObject.new
      lo.course_id, lo.title = @course.id, f.gsub('_',' ')
      lo.save!
    end
  end
end

# call to 'deactivate' a course
def unload_course
  unless params[:id].nil?
    @domid, @title = "available_#{params[:id]}", Course.find(params[:id]).title
    Course.transaction do
      LearningObject.destroy_all "course_id = #{params[:id]}"
      Course.destroy(params[:id])
    end
  end
end

Based on this, it would make sense to me if only the Courses table would ROLLBACK on an exception; however, I’ve tested this and it seems as though, if an exception is thrown in either case, neither the course nor the learning objects are saved. Granted, that is what I want to happen, I’m not completely convinced this will ROLLBACK the learning_objects table everytime. Do I need some sort of nested transaction, or is qualifying the block with Course good enough?

Comments

Jay Thursday, 08 Feb, 2007 Posted at 08:12PM

Looks good to me.

Ryan Thursday, 08 Feb, 2007 Posted at 08:14PM

Well, it seems to work fine, so I’ll keep it as is for now.

Shannon -jj Behrens Thursday, 10 Sep, 2009 Posted at 09:22PM

Let me see if I understand your question correctly. You’re wondering why you have to say Course.transaction and if that transaction will affect LearningObject. Is that right? You have to specify the model because Rails can be configured so that each model executes within a different database. Hence, you’re saying that you want the transaction to run in whatever database Course uses. However, the transaction spans the entire database. Hence, if LearningObject is in the same database as Course (which is really the norm), then it’s in the same transaction (which is really what people usually want).

Do you have something to say about this post?
Protected by Defensio Textile Formatting Tips

or

Ryan Heath | Site Management A Ruby on Rails production.

This site is a Formed Function. Formed Function LLC | @formedfunction | Get in Touch