Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Move hbtm associations to has_many through

  • Loading branch information...
commit 44a5a46555aefea490bb687e77e84ffce5687b19 1 parent c4b8a97
@ignar authored
View
4 app/controllers/countries_controller.rb
@@ -41,4 +41,8 @@ def visit
end
end
+ def statistic
+ #pluck
+ end
+
end
View
2  app/models/country.rb
@@ -2,6 +2,8 @@ class Country < ActiveRecord::Base
set_primary_key :code
has_many :currencies
+ has_many :user_countries
+ has_many :users, :through => :user_coutries
attr_accessible :name, :code
View
8 app/models/currency.rb
@@ -2,12 +2,14 @@ class Currency < ActiveRecord::Base
set_primary_key :code
attr_accessible :name, :code, :country_id
+ belongs_to :country
+ has_many :user_currencies
+ has_many :users, :through => :user_currencies
+
validates_presence_of :name
validates_presence_of :code
validates_uniqueness_of :code, :allow_blank => true
- belongs_to :country
-
def self.collected
all.select {|currency| currency.collected? }
end
@@ -19,4 +21,4 @@ def self.not_collected
def collected?
country.nil? ? false : country.visited?
end
-end
+end
View
21 app/models/user.rb
@@ -1,16 +1,13 @@
class User < ActiveRecord::Base
- has_and_belongs_to_many :currencies,
- :join_table => :user_currencies,
- :association_foreign_key => :currency_code,
- :uniq => true
-
- has_and_belongs_to_many :countries,
- :join_table => :user_countries,
- :association_foreign_key => :country_code,
- :uniq => true,
- :before_add => :add_all_currencies_of_country,
- :before_remove => :remove_all_currencies_of_country
+ has_many :user_currencies
+ has_many :currencies, :through => :user_currencies
+
+ has_many :user_countries
+ has_many :countries,
+ :through => :user_countries,
+ :before_add => :add_all_currencies_of_country,
+ :before_remove => :remove_all_currencies_of_country
attr_accessor :password, :password_confirmation
attr_accessible :email, :password, :password_confirmation
@@ -29,7 +26,7 @@ def toggle_visiting(country)
end
def visited?(country)
- countries.exists?(country.code)
+ self.countries.exists?(country)
end
def update_collection(currency)
View
7 app/models/user_country.rb
@@ -0,0 +1,7 @@
+class UserCountry < ActiveRecord::Base
+ belongs_to :user
+ belongs_to :country, :foreign_key => :country_code
+
+ validates :user, :presence => true, :allow_blank => false
+ validates :country, :presence => true, :allow_blank => false
+end
View
7 app/models/user_currency.rb
@@ -0,0 +1,7 @@
+class UserCurrency < ActiveRecord::Base
+ belongs_to :user
+ belongs_to :currency, :foreign_key => :currency_code
+
+ validates :user, :presence => true, :allow_blank => false
+ validates :currency, :presence => true, :allow_blank => false
+end
View
2  app/views/countries/index.html.erb
@@ -14,6 +14,8 @@
<h1>Countries</h1>
+ <div id="chart_div"></div>
+
<div class="filter">
<label for="name-filter">Name</label>
<input id="name-filter" name="name" type="text" />
View
2  app/views/layouts/application.html.erb
@@ -27,6 +27,8 @@
<footer>
CurrencyTracker &copy; Copyright 2011 by Smart Enterprises.
</footer>
+<%= javascript_include_tag "https://www.google.com/jsapi" %>
+<%= javascript_include_tag "statistic_charts" %>
<%= javascript_include_tag 'extensions', 'jquery-1.8.2.min', 'view_controller', 'simple_pie_chart', "rails.js", "countries", "currencies", 'update_elements' %>
</body>
</html>
View
1  config/routes.rb
@@ -4,6 +4,7 @@
resources :countries, :only => [:index, :show] do
member do
get :visit
+ get :statistic
end
end
resources :currencies, :only => [:index, :show] do
View
11 ctracker.org
@@ -1,10 +1,10 @@
#+STARTUP: showall
#+BEGIN: clocktable :maxlevel 2 :scope file
-Clock summary at [2012-10-23 Tue 17:57]
+Clock summary at [2012-10-25 Thu 02:21]
| Headline | Time |
|----------------------------------------------------------------------------------+---------|
-| *Total time* | *14:15* |
+| *Total time* | *16:45* |
|----------------------------------------------------------------------------------+---------|
| DONE Setup. Understand the task. Read existed code. | 0:37 |
| DONE Rake task | 0:07 |
@@ -29,6 +29,8 @@ Clock summary at [2012-10-23 Tue 17:57]
| DONE Filter on country page and "check/uncheck" controll | 1:04 |
| DONE Filter on currencies page | 0:37 |
| DONE Add apply controll | 0:14 |
+| TODO Progress chart | 0:38 |
+| DONE Rewrite from hbtm to has_many | 1:52 |
#+END:
#+STARTUP: hidestars
#+STARTUP: logdone
@@ -113,3 +115,8 @@ Clock summary at [2012-10-23 Tue 17:57]
* DONE Add apply controll
CLOSED: [2012-10-23 Tue 17:57]
CLOCK: [2012-10-23 Tue 16:50]--[2012-10-23 Tue 17:04] => 0:14
+* TODO Progress chart
+ CLOCK: [2012-10-24 Wed 21:59]--[2012-10-24 Wed 22:37] => 0:38
+* DONE Rewrite from hbtm to has_many
+ CLOSED: [2012-10-25 Thu 02:21]
+ CLOCK: [2012-10-25 Thu 00:29]--[2012-10-25 Thu 02:21] => 1:52
View
27 db/migrate/20121024213239_add_user_currencies_model.rb
@@ -0,0 +1,27 @@
+class AddUserCurrenciesModel < ActiveRecord::Migration
+ def self.up
+ remove_index "user_currencies", ["user_id", "currency_id"]
+ drop_table :user_currencies
+
+ create_table :user_currencies do |t|
+ t.column :currency_code, :string
+ t.column :user_id, :integer
+
+ t.timestamps
+ end
+
+ add_index :user_currencies, [:currency_code, :user_id]
+ end
+
+ def self.down
+ remove_index :user_currencies, [:currency_code, :user_id]
+ drop_table :user_currencies
+
+ create_table :user_currencies, :id => false do |t|
+ t.integer :user_id
+ t.integer :currency_id
+ end
+
+ add_index "user_currencies", ["user_id", "currency_id"]
+ end
+end
View
27 db/migrate/20121024222353_add_user_countries_model.rb
@@ -0,0 +1,27 @@
+class AddUserCountriesModel < ActiveRecord::Migration
+ def self.up
+ remove_index "user_countries", ["user_id", "country_code"]
+ drop_table :user_countries
+
+ create_table :user_countries do |t|
+ t.column :country_code, :string
+ t.column :user_id, :integer
+
+ t.timestamps
+ end
+
+ add_index :user_countries, [:country_code, :user_id]
+ end
+
+ def self.down
+ remove_index :user_countries, [:country_code, :user_id]
+ drop_table :user_countries
+
+ create_table :user_countries do |t|
+ t.integer :user_id
+ t.integer :country_code
+ end
+
+ add_index "user_countries", ["user_id", "country_code"]
+ end
+end
View
22 db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20121022102050) do
+ActiveRecord::Schema.define(:version => 20121024222353) do
create_table "countries", :id => false, :force => true do |t|
t.string "name"
@@ -31,19 +31,23 @@
add_index "currencies", ["code"], :name => "index_currencies_on_code", :unique => true
- create_table "user_countries", :id => false, :force => true do |t|
- t.integer "user_id"
- t.string "country_code"
+ create_table "user_countries", :force => true do |t|
+ t.string "country_code"
+ t.integer "user_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
end
- add_index "user_countries", ["user_id", "country_code"], :name => "index_user_countries_on_user_id_and_country_code", :unique => true
+ add_index "user_countries", ["country_code", "user_id"], :name => "index_user_countries_on_country_code_and_user_id"
- create_table "user_currencies", :id => false, :force => true do |t|
- t.integer "user_id"
- t.string "currency_code"
+ create_table "user_currencies", :force => true do |t|
+ t.string "currency_code"
+ t.integer "user_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
end
- add_index "user_currencies", ["user_id", "currency_code"], :name => "index_user_currencies_on_user_id_and_currency_code", :unique => true
+ add_index "user_currencies", ["currency_code", "user_id"], :name => "index_user_currencies_on_currency_code_and_user_id"
create_table "users", :force => true do |t|
t.string "email", :limit => 50
View
9 public/javascripts/countries.js
@@ -8,3 +8,12 @@ var update_chart = function(data){
chart.render();
});
};
+
+var chart = new window.Chart($("#chart_div")[0], {title: "hello"});
+chart.draw([
+ ['Year', 'Sales', 'Expenses'],
+ ['2004', 1000, 400],
+ ['2005', 1170, 460],
+ ['2006', 660, 1120],
+ ['2007', 1030, 540]
+ ]);
View
26 public/javascripts/statistic_charts.js
@@ -0,0 +1,26 @@
+;(function(){
+ google.load("visualization", "1", {packages:["corechart"]});
+ window.Chart = function(element, opts){
+ that = this;
+ this.element = element;
+ this.options = {
+ title: '',
+ hAxis: {title: 'Date', titleTextStyle: {color: 'red'}}
+ };
+ if(typeof opts == "object"){
+ for(var prop in opts){
+ if(opts.hasOwnProperty(prop)){
+ that.options[prop] = opts[prop]
+ }
+ }
+ }
+ return {
+ draw: function(raw_data){
+ var data = google.visualization.arrayToDataTable(raw_data);
+ var chart = new google.visualization.ColumnChart(that.element);
+ chart.draw(data, that.options);
+ return true;
+ }
+ };
+ };
+})();
View
4 public/stylesheets/scaffold.css
@@ -230,3 +230,7 @@ form ul.form_errors li {
div.filter {
clear: both;
}
+
+#chart_div {
+ width: 500px;
+}
View
6 spec/controllers/countries_controller_spec.rb
@@ -3,7 +3,7 @@
describe CountriesController do
include_context "logged in user"
- let(:country){ countries(:one) }
+ let(:country){ countries(:three) }
describe "GET index" do
it "should be success" do
@@ -56,4 +56,8 @@
end
end
+ context "GET statistic" do
+
+ end
+
end
View
2  spec/controllers/currencies_controller_spec.rb
@@ -2,7 +2,7 @@
describe CurrenciesController do
include_context "logged in user"
- let(:country){ countries(:one) }
+ let(:country){ countries(:three) }
let(:first_currency){ country.currencies.first }
describe "GET index" do
View
4 spec/fixtures/countries.yml
@@ -7,3 +7,7 @@ one:
two:
name: NameTwo
code: CodeTwo
+
+three:
+ name: NameThree
+ code: CodeThree
View
7 spec/fixtures/currencies.yml
@@ -13,4 +13,9 @@ two:
three:
name: NameThree
code: CodeThree
- country: two
+ country_id: CodeThree
+
+four:
+ name: NameFour
+ code: NameFour
+ country_id: CodeThree
View
9 spec/fixtures/user_countries.yml
@@ -0,0 +1,9 @@
+one:
+ id: 1
+ user_id: 1
+ country_code: CodeOne
+
+two:
+ id: 2
+ user_id: 1
+ country_code: CodeTwo
View
9 spec/fixtures/user_currencies.yml
@@ -0,0 +1,9 @@
+one:
+ id: 1
+ user_id: 1
+ currency_code: CodeOne
+
+two:
+ id: 2
+ user_id: 1
+ currency_code: CodeTwo
View
31 spec/models/user_country_spec.rb
@@ -0,0 +1,31 @@
+require 'spec_helper'
+
+describe UserCountry do
+ let(:user){ users(:one) }
+ let(:currency){ country(:one)}
+ subject{ user_countries(:one) }
+
+ it { should be_valid }
+
+ context "validation" do
+ it "should belong to user" do
+ subject.user.should be_kind_of(User)
+ end
+
+ it "should belong to currency" do
+ subject.user.should be_kind_of(User)
+ end
+
+ it "should validate presence of user" do
+ uc = UserCountry.new
+ uc.valid?
+ uc.errors[:user].should include("can't be blank")
+ end
+
+ it "should validate presence of currency" do
+ uc = UserCountry.new
+ uc.valid?
+ uc.errors[:country].should include("can't be blank")
+ end
+ end
+end
View
31 spec/models/user_currencies_spec.rb
@@ -0,0 +1,31 @@
+require 'spec_helper'
+
+describe UserCurrency do
+ let(:user){ users(:one) }
+ let(:currency){ currencies(:one)}
+ subject{ user_currencies(:one) }
+
+ it { should be_valid }
+
+ context "validation" do
+ it "should belong to user" do
+ subject.user.should be_kind_of(User)
+ end
+
+ it "should belong to currency" do
+ subject.user.should be_kind_of(User)
+ end
+
+ it "should validate presence of user" do
+ uc = UserCurrency.new
+ uc.valid?
+ uc.errors[:user].should include("can't be blank")
+ end
+
+ it "should validate presence of currency" do
+ uc = UserCurrency.new
+ uc.valid?
+ uc.errors[:currency].should include("can't be blank")
+ end
+ end
+end
View
38 spec/models/user_spec.rb
@@ -5,8 +5,11 @@
let(:first_country){ countries(:one) }
let(:second_country){ countries(:two) }
+ let(:third_country){ countries(:three) }
let(:first_currency){ currencies(:one) }
let(:second_currency){ currencies(:two) }
+ let(:third_currency){ currencies(:three) }
+ let(:fourth_currency){ currencies(:four) }
it { should be_valid }
@@ -61,27 +64,24 @@
describe "#toggle_visiting" do
it "should remember that user has visited this country if he wasn't" do
expect{
- subject.toggle_visiting(first_country)
+ subject.toggle_visiting(third_country)
}.to change{subject.countries.count}.by(1)
end
it "should set country unvisited if he was" do
- subject.toggle_visiting(first_country)
+ subject.toggle_visiting(third_country)
expect{
- subject.toggle_visiting(first_country)
+ subject.toggle_visiting(third_country)
}.to change{subject.countries.count}.by(-1)
end
it "should collect all currencies whilst you are in the country" do
- first_country.currencies << currencies(:one) << currencies(:two)
expect{
- subject.toggle_visiting(first_country)
+ subject.toggle_visiting(third_country)
}.to change{subject.currencies.count}.by(2)
end
it "remove currencies from collection if country was mark as visited by mistake" do
- first_country.currencies << currencies(:one) << currencies(:two)
- subject.toggle_visiting(first_country)
expect{
subject.toggle_visiting(first_country)
}.to change{subject.currencies.count}.by(-2)
@@ -90,51 +90,51 @@
describe "#visited?" do
it "should return true if user has visited particular country" do
- subject.toggle_visiting(first_country)
subject.visited?(first_country).should be_true
end
it "should return false if user has not visited particular country" do
- subject.visited?(second_country).should be_false
+ subject.toggle_visiting(first_country)
+ subject.visited?(first_country).should be_false
end
end
describe "#update_collection" do
it "should add currency to collection if user has no one" do
expect{
- subject.update_collection(first_currency)
+ subject.update_collection(third_currency)
}.to change{subject.currencies.count}.by(1)
end
it "should remove from collection if user has one in it" do
- subject.update_collection(first_currency)
+ subject.update_collection(third_currency)
expect{
- subject.update_collection(first_currency)
+ subject.update_collection(third_currency)
}.to change{subject.currencies.count}.by(-1)
end
context "making assumption that we collect only when visiting" do
it "country should be marked as visited on collection updating" do
expect{
- subject.update_collection(first_currency)
+ subject.update_collection(third_currency)
}.to change{subject.countries.count}.by(1)
end
end
it "should mark country as not visited if no collected currency ramains" do
- subject.toggle_visiting(first_country)
- subject.update_collection(first_currency)
+ subject.toggle_visiting(third_country)
+ subject.update_collection(third_currency)
expect{
- subject.update_collection(second_currency)
+ subject.update_collection(fourth_currency)
}.to change{subject.countries.count}.by(-1)
end
end
describe "#collected?" do
it "should indicate has user currency in collection or not" do
- subject.update_collection(first_currency)
- subject.collect?(first_currency).should be_true
- subject.collect?(second_currency).should be_false
+ subject.update_collection(third_currency)
+ subject.collect?(third_currency).should be_true
+ subject.collect?(fourth_currency).should be_false
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.