Skip to content
gnomet edited this page May 13, 2012 · 5 revisions

This page contains some advice and guidelines about the Kassi development. Please check this page before starting Kassi development.

Code Overview

Kassi is built with Ruby on Rails. Below there is a general code overview. It was originally written as a structure to a code review session that we held on one university course for people not yet familiar with Rails or Kassi. Even if it's mainly a list of words and half sentences, it can give some overview about the ways that we are using Rails in Kassi, even for people already familiar with it. And this wiki is editable, so feel free to improve it as you like. Add links, examples, more explanations etc.

  • Rails in general
    • Coder-friendly framework
    • Convention over configuration
    • DRY principle (Don't Repeat Yourself)
    • Extensibility: gems & plugins
      • Before you do something yourself, always check if it hasn't been done already by someone else!
    • MVC (Model, View, Controller)
      • separates business logic and user interface
      • built right into rails: almost impossible to not use it
      • models = business logic, views = user interface, controllers = communication between the two
  • Models
    • defines the structure and opertations for the data stored in Database
    • all db calls should be done via models
    • example: listing.rb
    • associations & chaining
    • usually no need to write sql
    • validations for contents
    • ASI-connections make some models (Person) little complicated, but don't stress about that. :)
      • might need to pass the cookie when requesting person details. Otherwise you can call methods just as any model
  • Views
    • in rails views are html with dynamic ruby components injected in between
    • We're using HAML for views (~ erb + html)
      • less code
      • proper way to indent html + erb mess
      • easier to read
    • sass (stylesheets-directory)
      • just like css but has some perks
      • variables
      • mixins ("functions")
      • nesting
      • inheritance
      • example: style.scss
      • .scss-files are transferred into regular .css files (public/styleheets)
      • Many times it's good to create own sass stylesheet for your external project! (and not modify style.scss)
    • layouts
      • example: application.haml
    • ordinary views
      • example: listings/index.haml
    • partials
      • chunks of code that can be inserted inside views or looped through
      • example: _listed_listing.haml
    • javascript: jquery (public/javascripts)
      • "industry standard"
      • a huge amount of plugins available
      • well compatible with rails 3
      • example: show.haml & kassi.js/initialize_comment_form
      • It's probably good to create own js file for your external project (and not modify kassi.js)
  • Controllers
    • This is where the request comes from the user's browser

    • example: ListingsController.rb

    • Fetches the required info from models (or inserts data to them) and then renders a view

    • example: close a listing

    • filters

      • avoid duplicating code
      • listings_controller/ensure_current_user_is_listing_author
    • session

      • temporary storage of data (valid for a single browsing session)
      • in Kassi saved in a cookie (a piece of code saved in user's computer)
      • information like knowledge about whether user has logged in etc.
    • flash

      • can be used to store a notification text for this request
      • example: closing a listing
    • respond differently to different format requests

      • rss, xml, json, jpg, ajax
      • example: close-method
    • complicated program logics is better to put in the model

      • "fat models, skinny controllers" principle
      • good rule of thumb if in doubt
  • Config
    • config.yml is the main file for server wide config variables
    • if you make new variables, be sure to update the config.example.yml too.
  • DB
    • Database structure is changed with migrations. There is a good help file at http://guides.rubyonrails.org/ Check it if you need to write migrations
    • There is a bug in schema dumper. Everytime you run "rake db:migrate" you need to edit the schema.rb file at the part where people-table is made. See old revisions for example. The reason is using GUID instead of normal id.
    • You'll notice this by almost all tests starting to fail strangely. Contact us when you need to touch migrations.. :)
  • Unit testing (rspec) ("spec" directory - "test" directory not in use since we use rspec)
    • Test a single model, controller or helper with a spec when you code it
    • Encouraged to write at least initial descriptions before coding the feature
    • example: listing.spec
    • Write tests with the attitude of describing behavior of the single component
    • No need to write double tests. If cucumber does the thing, no need for rspec.
    • However, you usually want to test what you wrote works, rspec is good way to do that as you don't need to care about the UI.
  • Integration testing (cucumber) ("features" directory)
    • Idea: customers could write code in plain english
    • In practise the coders usually do it themselves while writing the code
    • Example: user_creates_a_new_listing.feature
    • Two possibilities
        1. Dedicated test guy writes all the tests
        1. Coders write tests: first write a test and see it fail, then make the feature so that the test wont fail anymore
    • We are using the latter but your team can consider using the former so that everybody does not have to learn cucumber and rspec
  • Gems
    • "plugins" for ruby that are not directly "plugged in" to the app but used collectively by separate apps
    • other option is using "normal" plugins ("vendor" directory)
      • installed inside the program directory
    • We have preferred gem-version when available
    • command "gem" helps to maintain gems on your computer
    • command "bundle" helps to maintain gems used by the project
    • Gemfile lists the gems and versions used
    • Gemfile.lock is the excat list of the used versions of the gems in Gemfile
    • You can search for gems to help you in your tasks
      • e.g. interaction with google maps api
    • Currently many gems are fixed to certain specific version, because newer ones have brought in problems we haven't solved yet.
  • Sources for more information
  • Git:

Testing in practice

To run all the spec tests and the feature tests you need two commands rake spec and cucumber --tags ~@pending

If you have an ASI server available, it would good to run the tests also by using ASI, to keep things compatible. See Kassi and ASI for more info.

Rspec tests

In addition to running all the spec tests with rake spec you can also run a single file with for example rspec ./spec/helpers/locations_helper_spec.rb or even a single tests inside a file by pointing it with the line number: rspec ./spec/helpers/locations_helper_spec.rb:23 That makes it faster to test a single feature that you are changing. However, it's good practice to run the whole test set before sending your code for other people to use (or to develop on).

Cucumber tests (feature tests)

In addition to running all the spec tests with cucumber You can limit or select the tests with tags, for example exclude the tests that are marked as pending cucumber --tags ~@pending Or you can run single file of tests with cucumber features/listings/user_creates_a_new_listing.feature or even use a line number to select only a single test: cucumber features/listings/user_edits_his_own_listing.feature:33

Cucumber tests use Cabybara and selenium to test the actions in actual browser window (Firefox by default).