Giter VIP home page Giter VIP logo

join_model's Introduction

Join Model

The idea is to use join models to leverage Active Record’s has_many :through() macro. This is taken from Chad Fowler, Rails Recipes, 2012. (Chapter One)

The has_and_belongs_to_many() (habtm) macro is used for join tables, but those join tables (for example a ‘subscriptions’ table joining Magazines and Readers) do not have any data in them other than the relationship. For example, you would name a relationship table magazines_readers, and include only the id’s for Magazine and Reader.

The idea here is to store information in the join table, and it is called a join model. The relationship item has dates.

We will use a very simple notion of a Car, a Driver, and a Lease. The Lease has a Start Date, an End Date, and a Rate.

This example is also serving to explore the minimum number of files which are necessary to run Active Record and Rails.

Fowler calls this join model a first-class concept - a Lease. It exists by itself.

Here are the relationships. A Car has many Leases; but it also has many Drivers. A Driver has many Leases; but it also has many Cars. Each Lease belongs to a Car, and each Lease belongs to a Driver. The relationship between Driver and Car (and vice versa, Car and Driver) is the one using the :through. The relationship between Car and Driver is then implicitly many-to-many.

The interesting things are as follows:

You can do this: car.leases << lease. You have to do lease.save at the end in order to persist the relationships which have been added.

Then, you can do car.drivers or driver.cars. The relation is implicit, and works through the :through parameter of the has_many declarations.

ActiveRecord generates a SQL query like this: SELECT “cars”.* from “cars” inner join “leases” on “cars”.id = “leases”.car_id where ((“leases”.reader_id = 1))

Note that there is an interesting accessor with a SQL condition in the Car model.

This is run by using rails runner app/myscript.rb.

The steps to generating this app were:

  1. At the command prompt, create a new Rails application: rails new myapp -J --skip-bundle --skip-test-unit --skip-prototype (where myapp is the application name)

  2. Change directory to myapp and edit the Gemfile. Add therubyracer. Remove sqlite3 and replace it with mysql2; do bundle install.

  3. Edit the automatically generated database.yml file to use MySQL2 instead of sqlite3.

  4. Run rails g model driver name.

  5. Run rails g model car make model_name serial.

  6. Create the lease db/migrate file:

    class CreateLeases < ActiveRecord::Migration

      def change
        create_table :leases do |t|
          t.integer :driver_id
          t.integer :car_id
          t.date :start_date
          t.date :end_date
          t.string :rate
    
          t.timestamps
        end
      end
    end
  7. Run rake db:create.

  8. Run rake db:migrate.

  9. Run rake db:test:prepare.

  10. Add this to the Car model:

class Car < ActiveRecord::Base
  attr_accessible :make, :model_name, :serial
  has_many :leases
  has_many :drivers, :through => :leases
  # named accessor
  has_many :cheap_drivers,
    :through => :leases,
    :source => :driver,
    :conditions => ['rate < 5.0']
end
  1. Add this to the Driver model:

    class Driver < ActiveRecord::Base

    attr_accessible :name
    has_many :leases
    has_many :cars, :through => :leases
    

    end

  2. Add this to the Lease model:

    class Lease < ActiveRecord::Base

    attr_accessible :start_date, :end_date, :rate
    belongs_to :car
    belongs_to :driver
    

    end

  3. Run rake db:seed to create data. That looks like this:

    lease = Lease.create(:start_date => “2012-02-14”, :end_date => “2012-08-14”, :rate => “4.5”) car = Car.create(:make => “Mazda”, :model_name => “GLC”, :serial => “MG1”) driver = Driver.create(:name => “Babe”)

    # Wild syntax car.leases << lease driver.leases << lease

    lease.save

  4. Then run rails runner app/myscript.rb.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.