Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

Friday, 25 March 2011

Visual Studio coexistence - avec COM

Sorry, another boring one about info that's not easily available on the internet.

Added an extra version of Visual Studio recently and my COM-based ruby tool-kit for talking to Visual Studio (so I never need to use the (yuch) IDE) started popping the wrong version.

The link below has mixed solutions - most other internet references describe the "Microsoft Visual Studio Version Selector" which is registered for .sln files, which should detect the correc version or otherwise ask the user to choose. However this doesn't seem to apply to opening a solution via COM by "connecting" to it.

The "top" solution on the link below is probably a bit hacky for general use - Version Selector seems more sensible, however Version Selector doesn't work for COM object lookup.

So to summarise - choose your default by writing the registry value at:
HKLM\Software\Microsft\Windows\CurrentVersion\App Paths\devenv.exe
With thanks to the posters at: http://social.msdn.microsoft.com/Forums/eu/vssetup/thread/568e32af-d724-4ac6-8e8f-72181c4320b3

Sunday, 1 July 2007

has_many, :through (captain obvious)

You know how you would create a database to model a multiple relationship especially where each object is independent. eg Objects X and Y are modelled in tables X and Y, and the relationship between them is modelled by a table containing (key(X), key(Y)). So how to do this in Rails?

The documentation on join-associations, ie has_many :through, has the following example, but its missing some obvious details for the Rails-newbie who knows DB stuff, but doesn't know Rails.
  class Author < ActiveRecord::Base
has_many :authorships
has_many :books, :through => :authorships
end

class Authorship < ActiveRecord::Base
belongs_to :author
belongs_to :book
end
What's missing is the background stuff, how to get here, and what the DB needs to look like for this to work. The belongs_to association implies that the table associated with the object (eg Authorship) contains a foreign-key for that object. In this case the table "authorships" must have columns with foreign-keys for book and author. In the normal rails setup this means two columns called book_id and author_id.

So to get this example going head to your rails directory and run:
  ./script/generate model Authorship
./script/generate model Book
./script/generate model Author

You now have (among other things) 3 files in db/migrations called nnn_create_authorships (and book and author). The skeleton is already in place to create the "authorships" table. It needs the two foreign keys, so add them:
...
create_table :authorships do |t|
t.column :author_id, :integer # foreign key for author
t.column :book_id, :integer # foreign key for book
end
...
You can add any columns you want to the migration definitions for the other tables (names would be obvious) but bear in mind that there will (if you don't do anything special) be a hidden primary-key defined for each one as if you included the line:
  t.column :id, :integer
You don't need to add any external references to either the books or authors table.

To make these new tables take effect in the DB you use the db:migrate task. This allows you to move the databases between the different versions (this is the nnn_ prefix on the files in the db/migration directory). So use the command
  rake db:migrate
(you can choose any given version of your DB by appending VERSION=N to the line above - N corresponds to the nnn_prefix as above).

The belongs_to and has_many relationships are defined in app/models/authorship.rb (and author.rb, book.rb), so make them now. The has_many relationship in author will add a list called .books which hides all of the details of the join-relationship.

To see if any of this works its best to use the unit-tests for your model - eg with the example in test/units/author_test.rb. You should create fixtures for each model - these are sample data-sets that will be available for in your test-harnesses and development database, so go create some books, authors and authorships now. The generated fixtures will have the id: field, keep this, and remember you'll need this to fill in the authorship foreign-keys (book_id, author_id). Add values for the other fields (eg name of book,..).

To get our author_test working, and check the Author#books methods work we'll need the authorship and book data as well as author data. So add authorships and books to the fixtures list at the top of author_test.rb. If you don't do this you'll probably spend hours wondering why your tests fail, returning empty lists.

So create a quick test to verify everything is plumbed together properly, check that all of your test-data correctly fills out the lists as expected. Example test code:

# Test the books relationship works as expected using the test data defined in fixtures
def test_fixtures_books_relationship
author = Authors.find(1) # grab the author you defined with id: field of 1
assert author # ensure author was found

assert_equals 2, author.books.length # check the authorship connections
# you defined in your fixtures
book_names = ["Some book", "Another Book"]
author.books.each do |book|
assert book_names.find(book.name) # ensure that each of the books was
# one of the two expected
end
end
Run your test using:
  rake test:units