Assignment: Final Project Proposal and the Final Project
This is now final, though the list of “features” (item 8) will grow a bit. Stay tuned.
The Final Project (hereafter, FP) will be a web application designed and implemented by you. The basic idea is that you come up with a project of similar complexity to Assignments 4 and 5, with some additional features.
Proposal due date: Nov. 19. Proposals submitted earlier will be reviewed and approved earlier.
Final project due date: Dec. 17. Note: This due date is absolutely final, owing to Extension rules regarding examinations and final projects.
The requirements are as follows:
- You must write a FP Proposal and have it approved by your TA. (Approval means that you have an e-mail from the TA in which the TA writes: “I approve.” Your TA may tell you that the project is approved only if you make some changes in the proposal; if so, make the changes, and get that final approval!)The FP proposal talks briefly about what the application will do, what its models, controllers, and views are like, and what additional “features” you will implement — more on features below.
- Due date for the FP proposal: The due date for the final project proposal is: Nov. 19. If you can get your proposal in sooner, the staff will make every effort to provide feedback sooner rather than later. One thing you might consider is to give your TA a brief “pre-proposal” that provides in a paragraph some idea of what you intend to do before you write the full proposal; by this means, you might be able to get a bit of early tuning.
- The FP proposal must be a document written in plain English (i.e., not just an e-mail, and not a PowerPoint or KeyNote slide deck; it must be a PDF, an RTF file, a TXT document, or a ZIP of an HTML page). The audience of the FP proposal is an informed developer who needs to know the application’s scope and (high-level) how it will work. You should include enough information so that the developer would be able to evaluate whether or not he or she would want to implement the project. It is not a specification; it is a proposal. Please, do not provide a cover page, table of contents, list of figures, etc., etc.: Stick to plain sentences and paragraphs; lists can be useful for things like your descriptions of models and use cases (see below). How long should it be? My advice is to keep it as short (but clear) as you can; your TA will be able to tell you quickly if there is not enough detail, and then you will have time to resubmit.
- The FP should accomplish something. It should allow a user (or users) to get something non-trivial done. You should begin your FP proposal with a description of what the application accomplishes, and why you think anyone would be interested in it. Your FP proposal should “argue” a bit for the usefulness of the FP. If you like, include real-world data on who would benefit from the application, perhaps in terms of getting its task done cheaper, faster, or better. In the past, some of the best final projects have been: (a) a tool to help the developer with a hobby or other topic about which the developer is passionate; (b) a clone of part of an existing application (if you want to clone an existing application, there should be some kind of significant twist that differentiates your project); (c) something that would be of use to a family member; (d) something that would be useful at work; (e) an application that “mashes up” two or more web-based third-party APIs (e.g., Amazon’s or eBay’s services to provide information about products). One thing we haven’t seen much of is genuinely interesting games.
- Models: Your FP must have a list of Models that is of similar complexity to Assignment 4/5; i.e., five (or so) or more database tables, and relationships amongst the models. We expect you to use at least one has_many :through or, possibly, a pair of habtm relationships (as you will recall, John prefers has_many :through and hasn’t said much about habtm ["has and belongs to many"], but you can pick it up easily from AWDR). Models must define sufficient validations for the application to work properly (e.g., there should be no surprises because, say, two users have the same login name, if your application expects users to be unique). When you describe the models in the FP proposal, you NEED NOT include a diagram; you can simply list the models, what they represent, and their attributes, associations, and validations. The list should be easy to read. You do not need to list exhaustively all of the attributes — but we do need to hear about all of attributes that are functional.
- Use cases: Your FP must implement several use cases that exercise the models for one or more types of users. In the proposal and write-up, we like a list of sentences of the form “The user will be able to X.” For examples, see the requirements for last year’s MetricsMine application (http://e168f08.plugh.org/assignments/assignment-3-2/), or for the previous year’s ChildCare Co-Op (http://e168f07.plugh.org/2007/10/21/assignments-4-5-and-6-overview/). It can also be helpful to provide a user story or scenario (again, see MM or CCC). Your TA may well ask for more or less detail on this when reviewing your proposal.It will count negatively against your grade if there are models that are not exercised by the implementations of the use cases, or are exercised trivially. In your FP proposal, you must define the user (or users) carefully, and explain which use cases apply to which users. In large part this is where your FP proposal will talk about controllers. NOTE: The use cases play a special part in the FP Write-up (see below).
- Pages: You should itemize the most important pages and explain how the user experience in the use cases flows through those pages. In large part, this is where the FP proposal will talk about actions and views.
- Two Features: In addition to implementing models, controllers, and views, you must leverage two of the following additional features of Rails or plugins (depending on feedback from you, we may add to this list):
- E-mail (counts as only half a feature, unless the application makes significant use of e-mail). Send e-mail; but, more importantly for the e-mail feature, the e-mail must be functional to the app. In other words, it might notify users of a change of state in the application, and provide links that, when clicked, change the state of the application. In other words, merely sending notifications is not enough. (And e-mail confirmations sent by restful_authentication or other plugins is not enough.) You might also consider receiving e-mail. These topics are covered in AWDR.
- User management (counts as half): Adapt the login / registration code to use the Clearance Gem (http://github.com/thoughtbot/clearance).
- Ajax: Ajaxify as much as seems appropriate. Using Ajax on one or two pages will result in very little credit. Creative, dynamic use of Ajax will be reward, as well as systematic and consistent use of Ajax throughout the application. Ajax is covered in AWDR.
- REST. Provide a REST interface for at least one of the models. Ideally, you will implement nested resources. If you expose resources through REST, you must provide a sample client. Your best bet for a client is to write a simple application using ActiveResource. . . . covered in AWDR.
- Feeds: Expose an RSS or Atom feed with updates regarding the state of some aspect of your application. To get started: http://intertwingly.net/blog/2008/10/14/Rails-AtomFeedHelper-just-got-better
- Asynchronous jobs: Manage tasks through Workling (http://playtype.net/past/2008/10/2/workling_version_03_released/) or something similar.
- Uploading. Try paperclip: http://www.thoughtbot.com/projects/paperclip/; AWDR also provides some guidance on supporting uploads in Rails.
- Time zone handling. See http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/
- Internationalization or Localization: Provide a means to present your application in another language. THis can be a big topic: Discuss with your TA if you want to try it.
- Testing: Provide a complete test suite. This may count as two features. A serious attempt at this feature would require learning about rcov, possibly mock objects, and possibly an alternative (to RUnit) test framework such as Shoulda. If you want to do this, you should already be a testing zealot.
- Something else. You must get approval from your grader.
- If you propose an application that has significant domain complexity (say, a project with 15 tables and a lot of use cases), we may accept a proposal that specifies only one of the above features.
- A few notes about the final project packaging, writeup, internal documentation, and implementation (and we will likely have more to say in this department):
- The project must have the standard Rails directory organization (i.e., the result of running the “rails” command). We can’t accept assignments that have some kind of home-grown structure. It must be possible to start the server with “script/server” and so forth. Models, controllers, views, and migrations should obey the standard conventions regarding positioning in the directory structure, naming, etc.
- The project must run in the environment you set up for Assignment 0! (So Rails 2.3.3, etc.; please, no Rails 2.3.4 or later, or edge Rails!)
- Your rakefile must be based on the course Rakefile from the last version of Assignment 4/5. What you submit should be produced by “rake package.”
- It must be possible to run all migrations.
- The Rakefile for Assignment 4/5 does include a copy of the development database (db/development.sqlite3) in the ZIP. We do want this in case there are issues with your migrations. So don’t delete it prior to packaging.
- You must include sample data, i.e., a data migration that sets up sample users, data, etc.
- If you are using a gem or plugin that interfaces with a third-party (Amazon, eBay, etc), provide clear instructions on how to set any required components (including how to authenticate, if necessary) on the TA’s system.
- The project must be accompanied by a write-up, which is a plain TXT document (called readme.txt or an HTML document (called readme.html) which goes in the root of the project. Keep the formatting as simple as possible. The only reason we allow HTML is to make it a bit easier for you to include screenshots if you so desire.
- The write-up should cover the same topics as the proposal, but with a greater focus on implementation.
- As in the proposal, the write-up should include a list of use cases, and a clear explanation of how to exercise each use case; if you want to get credit for what you have done, provide us a way to see what you have done!
- The “crow”: On occasion, we have received submissions that do something incredibly cool, but for whatever reason the student forgets to tell us about it. Do not forget to “crow” (i.e., brag) about anything that is particular cool or amazing in your project. And don’t forget to tell us how to exercise that cool feature!
- As promised at the top of this page, we will provide another page with some details about how to create a great writeup. This document will also talk some about internal documentation.
You talked about the Clearance Gem in the features. Acutally I wanted to use OpenId authentication (just like the idea of OpenId) with this gem:
http://github.com/rails/open_id_authentication/
Is this credited as a feature too?
@Gabriel Hase
No. You can't have open id only.
If you want to use open id, you can use authlogic (http://github.com/binarylogic/authlogic) instead of clearance, and then use the open id plugin that comes with authlogic (http://github.com/binarylogic/authlogic_openid). There is a good Railscast: http://railscasts.com/episodes/170-openid-with-authlogic
Reason: You are going to want to have a regular user auth system as well as open id.
auth_logic + open id might count as a full feature rather than a half feature, but I am going to have to try it myself first. So assume that it would be only 1/2 of a feature, just like clearance.
About uploads: the AWDR example loads its image file into the database as a BLOB, which I thought was a discouraged practice. A brief glance at the Paperclip site suggests that it uses the file system to store uploaded files, which I believe is regarded as the preferred method. Is there a different position in the Rails world, or do my assumptions also hold true here?
@Mike Bond
The answer is: It depends.
I would recommend using Paperclip, because you can switch the storage to file, database, or Amazon S3, as you like.
The database has a HUGE advantage, which is that all of your model-related data is stored in one place. This is convenient because you can download all of your data; but, also, imagine that you have 4 or 5 Rails servers, all sharing a database. If you upload to the file system on server #2, how will the Rails instance on #3 get at the file? You would have to introduce some kind of synchronization or shared file system, which is a hassle.
So, my advice is:
-- Single Rails server: Upload to file system.
-- Multiple Rails servers, but light load, and small budget: Upload to db.
-- Multiple Rails servers, heavier load, a bit of budget: Learn about using Paperclip with Amazon S3. I am willing to do a screencast on this last topic if it is of interest.
Great summary, thanks, John. I imagine myself in small budget territory, so I will yield on the screencast offer unless other students are interested.
Also, is "Assignment 6" the appropriate drop box for the FP proposal?
@Gabriel Hase
I looked at the Open_ID lib you are speaking of. Be careful with that. When I was playing with it a few months ago, there were several bugs. (i.e. I had an Admin user that I manually made admin, and after 3 or 4 weeks, I logged in as that user and it gave me a totally new hash; i considered this extremely dangerous and ditched that library altogether). I am going to look into AuthLogic.
[quote]Also, is "Assignment 6" the appropriate drop box for the FP proposal?[/quote]
I'd also like to know the answer to this. I put mine in the 'Final Project' drop box and also e-mailed it to my TA.
@Jeff Ancel
Thanks for the hint! I didn't have any problems so far though. Did you use the official github version?
what time is the FP due on the 17th? I'm hoping midnight ;)
I mean 11:59 pm the 17th ;)
@Ron Newman
I renamed the "Assignment 6" dropbox to "Final Project Proposals."
I originally imagined that people would e-mail their proposals, but the dropbox is ok as well; if you submit early, though, DO e-mail your TA so they know to pick it up from the dropbox.
@Lateral Punk
I assume you mean the final project itself?
We will enter the grading frenzy on the morning of Dec. 18th, so you can hand it in quite late on Dec. 17th / early on the 18th. Let's say by 5 AM EST on Dec. 18th.
@john
How about the FP proposal that is due tomorrow (19th) - would it be due before 11:59pm? Also, is submitting it in a Word doc reasonable?
@Ben Ho
If you must, hand it in very late on the 19th, or into the wee hours on the 20th. Let's say 4 AM on the 20th.
Word is ok, but save it in one of the older, more portable formats: Word 6.0 / 2000 format (not .docx). Saving as .rtf would be best, or get a PDF. (This free converter may work -- http://www.scribd.com/landing/pdf_conversion -- haven't tried it myself.)
Hi John
How you doing
Question:
Should we submit Final Project Proposal as email attachment to our TF or just drop it as a regular assignment in the dropbox.
I 've already send my “pre-proposal” or proposal version 1.0 to Jonathan and get quick feedback from him. I revised it, converting it to PDF format, and call it a final version. Since today's is the due day for proposal, I 'd like to make sure where should I to drop it first.
I assume that just a plain PDF format would be ok, don't have to zip it.
Thanks
@qiangwu
I recommend:
-- Put it in the dropbox.
-- E-mail your TA and tell him that it's there.
Advantage: It won't get mislaid.
Just FYI the above link for the Child Care Co-op seems to be broken. Just perusing for another point of reference for the proposal.
Thanks!
@Brian Mantenuto
Thanks, Brian. Here's the link, and I'll patch up what's above:
http://e168f07.plugh.org/2007/10/21/assignments-4-5-and-6-overview/
In AWDR pg. 300, DHH advises against seeding data in your migrations, as do various websites. However, their technique, putting data in db/seed.rb, is supposedly available beginning in Rails 3. Is it doable and advisable now in 2.3.3?
@Mike Bond
Seed data is for 2.3.4; 2.3.3 doesn't have it. Here's a nice railscast on it http://railscasts.com/episodes/179-seed-data
If you think your database needs data, migrations are one way to do it -- if you need it, do it. The concern DHH has is that if your models get out of synch, you can have issues; but sometimes defining one-use models INSIDE the migration can alleviate this issue.
Routes/nested resources question:
In HW4/5, we had entities like annotations and index_entries that "belonged to" publications and users, but they were only mapped in routes.rb as nested resources under the Publication, which excluded an additional mapping under the User. According to various readings, such as the Chapter 6 download from Practical Rails Projects, such a route mapping declares "that a particular resource is only valid within the subcontext of another resource." This seems to make sense for an annotation to a publication, which has no other valid context, but suppose that an entity could live a double life as both an independent entity and in certain cases as a sub-entity. For example, if we had a stamp collecting website, one could view stamps on their own or view them as they relate to a particular user. Let´s say the user has a collection and the collection contains stamps. The stamps are not only valid within the subcontext of a particular user´s collection; they are valid in numerous contexts. This relationship is defined in the models through has_many and belongs_to, but would we want to also define a nested route in routes.rb for the collection-to-stamps portion? It seems to restrict us too much.
The heart of the matter is that I am perhaps not clearly seeing the difference between 1) defining model associations and 2) defining nested resources in routes.rb. I see in sample controllers that we can select only those annotations/collections/stamps/etc. that belong to the current_user by designating current_user.publications.build, but such a relation is not defined anywhere in routes.rb.
Should I restrict my thinking about routes/resources in some way or understand some nuance about the difference between model associations and nested resources?
Thanks!
I tried using http://playtype.net/past/2008/10/2/workling_version_03_released/ to run a background process for my project and I had enough trouble that I eventually gave up. The biggest problem was that the Workling module references memcache even when you want to use the 'SpawnRunner' to just fork off another process w/o detaching that process. There were several memcache plugins on github and I wasn't sure which was compatible with Workling. (Maybe I should have looked harder).
I then tried BackgroundRB at git://github.com/gnufied/backgroundrb.git. This had syntax errors, as downloaded, because it apparently hasn't been updated for Ruby 1.9. I fixed those syntax errors and I've successfully used it to run a statically scheduled background job configured in a YAML file. The background job is successfully able to read ActiveRecords. (Yeah!)
If someone wants to try BackgroundRB for background processing then leave a message here and I can email a tarball of the modified code to John to put up on this site.
I am using Paperclip for file (image) uploads. Installation can be a pain if one does not have all the right tools, since git didn't work. It is available as a gem, though, which worked out. http://wiki.github.com/thoughtbot/paperclip/installation
You must also install ImageMagick.
Later, there was an Internal Server Error which is caused by Rake 1.0.0. I uninstalled it and reinstalled the gem, which brought me to Rake 1.0.1. Success!
If anyone has Paperclip installation problems, these may be some things to try.
Hi - in the above instructions, the last item listed in item 9.8. is *As promised at the top of this page, we will provide another page with some details about how to create a great writeup. This document will also talk some about internal documentation.* Where can we find this sample writeup? Thanks.
@Karin Berger
Right here: http://e168f09.plugh.org/assignments/assignment-note-tips-for-the-final-project-and-the-final-project-writeup/
It's not a "sample," though, but rather some details about how to create a great writeup . . .
@Mike Bond
You are right that there isn't a lot of clarity about nested vs. non-nested resources.
If you think that it makes sense to list annotations (say) outside of the context of a publication, then you definitely want it to be a top-level resources. In this case, requesting /annotations should return ALL annotations.
If you want it to be nested, then you want it to be the child of a resourceful "has_many" declaration. This means that you access via /publications/1/annotations. Now the annotations returned should be only those for Publication 1. Typically, you implement this with a before_filter that finds the Publication (based on params[:publication_id]) and saves the right publication under an instance variable (@publication). It is a very similar constraint to what we do with the current_user in the publications app for assignments 4 and 5.
So far it's pretty easy. The hard part comes when you decide that you want a resource to play both ways. I'll see if I can cook up a sample application that shows how to do that.
I created a gmail account for use with my project. The address is e168f09@gmail.com (;-) and its password is our standard course password. I'm using this for all the emails *from* my project because I don't want to hand out my normal email account. This account can easily be shared by anyone in the course (now, or in the future) who also needs to use ActionMailer.
It takes some doing to get ActionMailer to work with gmail because gmail uses SSL/TLS. See the web page http://ionrails.com/2009/07/27/sending-mail-via-gmail-with-rails-actionmailer/ for details.
@john
Would acts_as_list (as demonstrated in class) work in the context of individual users? I may be running into the same issue of having resources play both ways.
I have users who have their own lists, which in turn have games. The games are available on their own, too, and may appear on many lists, so they are not monogamous. (These are my two-way resources.) The acts_as_list plugin would be very helpful for me to do the AJAX ordering tricks you demo'd, but the basic implementation puts a :position attribute in the model to be manipulated, in this case, the games. But since they are not monogamous, it won't work that way.
Until deciding to try acts_as_list, I had built up the lists via an associations matrix. Perhaps to use acts_as_list, one could use the list as the parent and the association row as the child, even though it has its own child, the game.
@Mike Bond
I don't know.
If the games are shared (many-to-many relationship between users and games), but you want the positions to be per-user, then you would probably want your positions to be on a join table between users and games.
Example (U = user, G = game, P = position)
U G P
1 1 1
1 2 2
1 3 3
2 1 4
2 4 5
2 5 6
3 1 7
3 2 8
3 6 9
Now, suppose you drag U 2's G 5 to the top position (as U 2 sees it):
U G P
1 1 1
1 2 2
1 3 3
2 5 4
2 1 5
2 4 6
3 1 7
3 2 8
3 6 9
That's ok, right? As long as the view is constrained to U 2's games, and you rely on the positioning in the join table, you might be ok.
John
@john
It turns out to work out as you stated, which is how my DB was designed, but without the AJAX magic. In rewiring it for the plugin, I originally wanted to go straight from the list to the game, which was a bad idea. Also, a user can only see his own position, so instead of running from 1 to 9, it would be the user's own local rankings, which is useful for future aggregation. Life is good! Thanks for the ideas. Modified example follows:
U G P
1 1 1
1 2 2
1 3 3
2 5 1
2 1 2
2 4 3
3 1 1
3 2 2
3 6 3
For my project I need to do something simple: manage my clients contact info information e.g. (home/bus) phone, address, etc. These are not *users* in the sense of Clearnace users or something...they are just my ship to clients and stuff. Is there a gem I can use for this? Or should I modify Clearance though my clients aren't actually user? I just want some sort of gem to maintain the necessary contact info for me so I don' thave to ;)
@Lateral Punk
That sounds like a quick model, view, and controller to me!
call me lazy then ;)
ok how about this...does clearance support user groups/ security groups? Power Users, Regular Users, etc...
@Lateral Punk
OK, "you're lazy."
If you go to the Clearance Wiki at github.com, I believe you will see mention of various add-ons to Clearance that might provide for roles.
So rude!
hehe..
i'l look into roles
Why is it that when you do a scaffold with a model that has t.references, that the views that are created don't have _id in the parms? this is annoying, or am i doing someting wrong? I'm having to go thorugh all my views and put _id everywhere....
i do
t.references :user
for example...
I had the above problem because when I tried to create a new object that references another one, I would get this error:
ActiveRecord::AssociationTypeMismatch in RollsController#create
Style(#2154128508) expected, got String(#2152049396)
Roll has obvioulsy style_id since i used references...though all the view code refers to it as :style
what's even more weird, in the model code, if I do :validates_presence_of :style it works!!
John, can you please help clarify _id & references once and for all...I've hit this road block before I feel
I think it's best not to use t.references
just do
script/generate scaffold style fabric_id:integer...
this works the best, you just have to put the approproate associatiosn thats all
I'm having similar issues with using references with scaffolding. Is there a right way to do this or is references just something that scanffold doesn't understand?
The script/generate scaffold style fabric_id:integer... trick seems like a bit of a hack to me and I hope that is a cleanner way to do this.
@Lateral Punk
@DavidL
A couple of things:
Saying script/generate style fabric_id:integer is NOT a hack; there was a time when the "references" pseudo-type didn't exist.
In any case, it works for me. E.g.,
script/generate scaffold user first_name:string
script/generate scaffold post user:references title:string
Then go into user.rb, and add: "has_many :posts"
Then:
script/console
j = User.create!(:first_name => 'John')
j.posts.create(:title => 'my first post')
j.posts
Post.find(1).user
etc.
By all means, though, edit your migrations and models until they work. script/generate scaffold is just a tool to get you started. You really don't need to use scaffolding at all -- you know enough Rails now that you could create the models, controllers, and views manually. The chief place where the scaffolding is helpful is getting the controllers right for "RESTFul" handling -- but you may not need that.
@Lateral Punk
Regarding some relationship between the "references" declaration and the views:
You have to edit those views. Suppose you are showing the form to add a post (like a blog post). The scaffolding has done the best it can to put SOMETHING in place to remind you to deal with the user. (It is obviously just plugging in :user [for example] as though it's an ordinary attribute.) But, really, who is going to own that blog post? Answer: The currently-logged-in user. So you are typically going to REMOVE that part of the view anyway. The scaffold can't read your mind though: Perhaps you would replace:
< %= f.label :user %>
< %= f.text_field :user %>
With a drop-down of all users. You'd still have to edit it. When you create a blog post, in other words, the scaffold generator can't really know in advance whether you are going to populate the user to whom the post belongs before displaying the form; or given the user the change to pick from a drop-down. You have to change the code in accordance with your requirements.
OK?
To summarize:
Yes, it is awkward that the generator doesn't treat user:references as a regular attribute. If it did put in user_id that would be kind of weird, because it would be exposing a foreign key value in the view. It really can't know how you would want it to work, so it is just as well that it generates "broken" code because you would have to fix it anyway.
As always, thanks John for your clear explanations. Hmm, I think I'll revert back to references then, just so it's clear to future developers who look at my code....thank god for script/destroy!
thanks
I just did gem install seed-fu and darn it, it installed 2.3.5 of activesupport et. gang!
Am I screwed? should I uninstall like in Assignment 0? Or am i going to be fine (i recall 2.3.4 was the issue)...
darn it!
Seems though my app is still using 2.3.3:
=> Booting WEBrick
=> Rails 2.3.3 application starting on http://0.0.0.0:3000
I wonder if seed-fu will work...??
Anyways, should I be worried or not about 2.3.5?
I reverted...seed-fu gave too many errors when doing rake db:migrate...it was weird...I'll stick with seed data in migrations for now..or devise my own rake db:seed task (if i know how)
For those you are interested, I just took the best of seed-fu which was the rake task and put it into my own rakefile:
# NOTE: adapted from seed-fu
task_name = Rake::Task.task_defined?("db:seed") ? "seed_fu" : "seed"
namespace :db do
desc <<-EOS
Loads seed data for the current environment. It will look for
ruby seed files in /db/fixtures/ and
/db/fixtures//.
By default it will load any ruby files found. You can filter the files
loaded by passing in the SEED environment variable with a comma-delimited
list of patterns to include. Any files not matching the pattern will
not be loaded.
You can also change the directory where seed files are looked for
with the FIXTURE_PATH environment variable.
Examples:
# default, to load all seed files for the current environment
rake db:seed
# to load seed files matching orders or customers
rake db:seed SEED=orders,customers
# to load files from RAILS_ROOT/features/fixtures
rake db:seed FIXTURE_PATH=features/fixtures
EOS
task task_name => :environment do
fixture_path = ENV["FIXTURE_PATH"] ? ENV["FIXTURE_PATH"] : "db/fixtures"
seed_files = (
( Dir[File.join(RAILS_ROOT, fixture_path, '*.rb')] ).sort +
( Dir[File.join(RAILS_ROOT, fixture_path, RAILS_ENV, '*.rb')]).sort
).uniq
if ENV["SEED"]
filter = ENV["SEED"].gsub(/,/, "|")
seed_files.reject!{ |file| !(file =~ /#{filter}/) }
puts "\n == Filtering seed files against regexp: #{filter}"
end
seed_files.each do |file|
pretty_name = file.sub("#{RAILS_ROOT}/", "")
puts "\n== Seed from #{pretty_name} " + ("=" * (60 - (17 + File.split(file).last.length)))
old_level = ActiveRecord::Base.logger.level
begin
ActiveRecord::Base.logger.level = 7
ActiveRecord::Base.transaction do
# Just load regular .rb files
#
File.open(file) do |file|
chunked_ruby = ''
file.each_line do |line|
if line == "# BREAK EVAL\n"
eval(chunked_ruby)
chunked_ruby = ''
else
chunked_ruby << line
end
end
eval(chunked_ruby) unless chunked_ruby == ''
end
end
ensure
ActiveRecord::Base.logger.level = old_level
end
end
end
end
then run
rake db:migrate;rake db:seed
with output:
== Seed from db/fixtures/seed_roll_statuses.rb ======================
== Seed from db/fixtures/development/seed_colors.rb =============================
== Seed from db/fixtures/development/seed_fabrics.rb ============================
== Seed from db/fixtures/development/seed_machines.rb ===========================
See I like that it picks up from different environments..this is useful because then for production you don't put any fake user generated data, and for all the common stuff, just put it in db/fixtures the root...nice
For those you are interested, I just took the best of seed-fu which was the rake task and put it into my own rakefile:
#Darn it, seems like this comment field will not take too much source code. if anyone is interested, just look at http://github.com/mbleigh/seed-fu/blob/master/tasks/seed_fu_tasks.rake
and remove any of the zlib logic
then run
rake db:migrate;rake db:seed
with output:
== Seed from db/fixtures/seed_roll_statuses.rb ======================
== Seed from db/fixtures/development/seed_colors.rb =============================
== Seed from db/fixtures/development/seed_fabrics.rb ============================
== Seed from db/fixtures/development/seed_machines.rb ===========================
See I like that it picks up from different environments..this is useful because then for production you don't put any fake user generated data, and for all the common stuff, just put it in db/fixtures the root...nice
sort of related to the above seed stuff, but could be a totally different question, how do you "flush" sql commands to the database e.g. I do a create! in one of my seed file, and the next seed file depends on the data to be *in* the database from the first seed file. Right now the 2nd seed says that it can't find the thing by name since it doesn't exist. I did a quick test, and I put the create! into a migration and then tried the same test, and it did work. What's so special about a migration and create! ? Does it flush it?
I'm doing that whole meta-programming on look-up tables. It would be essential for me to get this working or it'll suck :(
ignore last question about flush...seems it's something else like when i call the meta function
@Lateral Punk
Could you summarize any questions you have at this point . . . ?