Giter VIP home page Giter VIP logo

counter_culture's People

Contributors

aaronrenner avatar adzap avatar bencollab avatar chrisbr avatar demillir avatar dlackty avatar jaimeiniesta avatar jogaco avatar ken3ypa avatar key88sf avatar kmcgaire avatar luvtechno avatar madao-3 avatar magnusvk avatar mockdeep avatar nisanthchunduru avatar patrickdavey avatar progm avatar r7kamura avatar reidab avatar robertomiranda avatar ruslanhassonov avatar samirph avatar stefschenkelaars avatar swrobel avatar taher-ghaleb avatar takuan-oishii avatar tiagolupepic avatar timdiggins avatar tr4b4nt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

counter_culture's Issues

Fix counts not updating incorrect float values correctly. Reopening issue #41

I'm stilling having problems where the counter_culture_fix_counts isn't accurately updating float counters. In my app the floats are rounded to whole numbers, and are often reset to 0 when the sum of counts is not 0.

I have added a spec (and am working on making it better). I pushed out what I have so far, and you can see what I am trying to test. Look for the spec titled "should fix a sum counter cache correctly" line 961.

https://github.com/atstockland/counter_culture

Thanks, Magnus

command rails d....

rails d counter_culture Xxx xxx

will print

remove db/migrate/xxxxx.rb but no this file

Callbacks not triggered when using transactional fixtures in RSpec

I've just come upon this issue, will flesh out here more when I have extra details / specs. But incase anyone has seen it:

If I have config.use_transactional_fixtures = true (the default), then I found that the callbacks to increment/decrement the counters weren't being called in my RSpec specs.

I outlined the problem in this gist, demonstrating how it only seemed to occur when running specs, and not from the console. @JonRowe was kind enough to point me to use_transactional_fixtures, and sure enough, setting that to false resolved the issue.*

I'm using the postgresql adapter (I see the specs use sqlite3), not sure if that's relevant.


* I used database_cleaner instead.

Help undersanding why I'm getting so many wrong counts

Hi! First of all, sorry if this space is strictly about bugs.. I don't think I've got into one. But I really really could use some help!

I don't understand why this is failing so horribly. I have this related models:

class Match < ActiveRecord::Base
  has_many :predictions

  after_save :score_predictions

  # I'm feeling this method might be a problem but I couldn't keep somewhat
  # sane counts without _fix_counts here
  def score_predictions
    predictions.find_each(&:score!)
    Prediction.counter_culture_fix_counts
  end
end

class Prediction < ActiveRecord::Base
  belongs_to :partial_score
  belongs_to :match

  counter_culture :partial_score, column_name: 'total',
    delta_column: 'points'

  # I tried doing it from PartialScore with a counter_culture call but
  # couldn't make it work
  counter_culture [ :partial_score, :score ], column_name: 'prediction_total',
    delta_column: 'points'

  counter_culture [ :partial_score, :score ],
    column_name: Proc.new { |p| p.exact? ? 'exacts' : nil },
    column_names: { [ 'predictions.exact = ?', true ] => 'exacts' }

  def score!
    # method that calculates +points+ and sets column based on object and
    # match state and finally saves
    save
  end
end

class PartialScore < ActiveRecord::Base
  has_many :predictions
  belongs_to :score
end

class Score < ActiveRecord::Base
  has_many :partial_scores
end

I'm getting really wrong counts, every time. I'm sure it's something I can't
see here. Sorry again for using this issue kinda as rubber duck debugging.

Counter Culture getting incorrect count with after_create hook

We are having a problem with our implementation of counter cache. When we have an after_create method it ends up doubling up the count (returning 2 instead of 1).

Here is a simple setup

class Issue < ActiveRecord::Base
  belongs_to :order
  counter_culture :order
  after_create :set_ticket_number
  def set_ticket_number
    update_attribute(:ticket_number, 200000+id)
  end
end

class Order < ActiveRecord::Base
  has_many :issues
end

Then in the console

>> o = Order.first
=> #<Order id: 1, issues_count: 0>
>> o.issues_count
=> 0
>> o.issues
=> []
>> o.issues.create
   (0.1ms)  BEGIN
  SQL (0.5ms)  INSERT INTO `issues` (`order_id`, `ticket_number`) VALUES (1, NULL)
  Order Load (0.7ms)  SELECT `orders`.* FROM `orders` WHERE `orders`.`id` = 1 LIMIT 1
   (0.3ms)  UPDATE `issues` SET `order_id` = 1, `ticket_number` = 1217251 WHERE `issues`.`id` = 1017251
   (0.7ms)  COMMIT
  SQL (0.6ms)  UPDATE `orders` SET `issues_count` = COALESCE(`issues_count`, 0) + 1 WHERE `orders`.`id` = 1
  SQL (0.5ms)  UPDATE `orders` SET `issues_count` = COALESCE(`issues_count`, 0) + 1 WHERE `orders`.`id` = 1
=> #<Issue id: 1017251, order_id: 1, ticket_number: 1217251>
>> o.issues.size
=> 1
>> o.reload
  Order Load (0.4ms)  SELECT `orders`.* FROM `orders` WHERE `orders`.`id` = 1 LIMIT 1
=> #<Order id: 1, issues_count: 2>
>> o.issues_count
=> 2

Switching back to the Rails counter_cache: true fixes it, also commenting out the after_create fixes it.

Do you have any ideas why it might be doing that? I took a look at the source shortly and thought I might have been interfering with your after_create hook.

Thanks for the awesome gem, it's stopped a lot of our dead lock issues.

count columns is not automatically updated, have to run counter_culture_fix_counts to fix each time add new record

hello, I'm using counter_culture to create survey applications
the problem is each time I add citizen the count columns is not automatically update
I have to go to console and run Citizen.counter_culture_fix_counts
below is my model and controller for reference
I'm using rails 4 and nested_attributes
thank you for help

model

class Familycard < ActiveRecord::Base
    has_many :citizens  , :dependent => :destroy
  accepts_nested_attributes_for :citizens, :allow_destroy => :true
end

class Citizen < ActiveRecord::Base
  belongs_to :familycard

  counter_culture :familycard, 
    :column_name => Proc.new { |model| "#{model.sex}_count"},
    :column_names => {
      ["citizens.sex = ? ", 'male'] => 'males_count',
      ["citizens.sex = ? ", 'female'] => 'females_count'
    }

  counter_culture :familycard

  counter_culture :familycard, 
    :column_name => Proc.new { |model| "#{model.job}_count"},
    :column_names => {
      ["citizens.job = ? ", 'Entrepreneur'] => 'Entrepreneurs_count',
      ["citizens.job = ? ", 'House wife'] => 'housewifes_count',
      ["citizens.job = ? ", 'Student'] => 'students_count',
      ["citizens.job = ? ", 'Veteran'] => 'veterans_count'
    }    

end

controller

class FamilycardController < ApplicationController
  def new
    @familycard = Familycard.new(:citizens => [Citizen.new])
  end

  def create
    @familycard = Familycard.new(familycard_params)
    if @familycard.save
      flash[:success] = "Data Saved" 
      redirect_to familycards_path 
    else
      render 'familycards/familycard_form'
    end
  end

Issue with column_names when using a join class

I have a counter setup on a class that is the join class between two models. It should change the counter only when the associated parent object has the flag is_deleted set to false. I can't seem to get manual populating working for it though as the column_names hash seems to generate an error when a manual fix is run.

I couldn't figure out how to get this join to work (I'm using Squeel for it) for this counter and get this error:
NoMethodError: undefined method `%' for #ActiveRecord::Relation:0x000000057bf020

Here's the class:

class EventCreation < ActiveRecord::Base
attr_accessible :event_id, :user_id

belongs_to :event
belongs_to :user

counter_culture :user,
:column_name => Proc.new {
|model| !model.event.is_deleted ? 'event_creations_count' : nil
},
:column_names => {
[joins{event}.where{event.is_deleted == false}] => 'event_creations_count'
}

end

Nil issue

I'm using Rails 3.2.12 and counter_culture 0.1.11...

class Cat < ActiveRecord::Base
has_many :lives
end

class Live < ActiveRecord::Base
belongs_to :cat
counter_culture :cat
end

In the migration:
add_column :cat, :lives_count, :integer, :null => false, :default => 0
Cat.counter_culture_fix_counts

undefined method each' for nil:NilClass ..../gems/counter_culture-0.1.11/lib/counter_culture.rb:58:incounter_culture_fix_counts'

Fix_counts breaking on dynamic column name with enum

I have a classes User and Item, each of which has columns haves_count and wants_count, which I am trying to apply counter_culture to. They are joined by has_many through relationships with a class CollectionRecord.

# User.rb
has_many :collection_records
has_many :items, :through => :collection_records


# Item.rb
has_many :collection_records
has_many :users, :through => :collection_records

CollectionRecord has an enum status: [:have, :want], which I'm trying to use to define the counter column names. I have my counters set up in CollectionRecord like so:

# CollectionRecord.rb

belongs_to :item
    counter_culture :item, :column_name => Proc.new {|cr| "#{cr.status}s_count" }, 
        :column_names => { ["collection_records.status = ?", CollectionRecord.statuses[:have] ] => 'haves_count', [ "collection_records.status = ?", CollectionRecord.statuses[:want] ] => 'wants_count' }
    belongs_to :user
    counter_culture :user, :column_name => Proc.new {|cr| "#{cr.status}s_count" }, 
        :column_names => {[ "collection_records.status = ?", CollectionRecord.statuses[:have] ] => 'haves_count', [ "collection_records.status = ?", CollectionRecord.statuses[:want] ] => 'wants_count'}

Which is copied from https://github.com/magnusvk/counter_culture#handling-dynamic-column-names and adapted for an enum based on http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html. When I run CollectionRecord.counter_culture_fix_counts I get:

NoMethodError: undefined method `statuses' for #<Class:0x000001039dfc70>
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/dynamic_matchers.rb:26:in `method_missing'
    from /Users/jaime/Desktop/CompleteSet-Rails/app/models/collection_record.rb:14:in `<class:CollectionRecord>'
    from /Users/jaime/Desktop/CompleteSet-Rails/app/models/collection_record.rb:4:in `<top (required)>'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:443:in `load'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:443:in `block in load_file'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:633:in `new_constants_in'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:442:in `load_file'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:342:in `require_or_load'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:480:in `load_missing_constant'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:180:in `const_missing'
    from (irb):101
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands/console.rb:90:in `start'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands/console.rb:9:in `start'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands/commands_tasks.rb:69:in `console'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

Furthermore, I get this same error anytime I try to do anything else with the class, not just when I try to fix the counts. I've tried taking the class name off of the front and just using something like :column_names => { ["collection_records.status = ?", statuses[:have] ] => 'haves_count', ... but that gives the same error. It does work if I replace CollectionRecord.statuses[:have/:want] with the actual values (0/1), but that seems smelly and error prone.

Any idea why using the mapping breaks the entire class, or what I can do to fix it?

#counter_culture_fix_counts doesn't work for conditional counter cache

I declared counter_culture as following:

class Product < ActiveRecord::Base
  ...
  counter_culture :product_type, column_name: Proc.new {|model| model.active? ? 'products_count' : nil }
end

And I'd like to fix counts for all count declare in Product model, so I run Product.counter_culture_fix_counts but it raised exception

RuntimeError: Must provide :column_names option for relation [:product_type] when :column_name is a Proc; 
you may skip this relation with :skip_unsupported => true

Running counter_cultured model's after_update hook

Currently when the count column is updated any update callbacks in the counter_cultured model are not running. Imagine there is a after_update hook that does something (e.g. set the status column to be "FULL") when the count exceeds certain number. It would be nice if those callbacks are not skipped when the count is updated by counter_culture.

Fixing counts on multi-level STI models doesn't work

We have a multi-level relation with an STI model at the base for our email system. We're tracking email clicks and views. So, it looks like this:

EmailEvent::Viewed/Clicked -> Email -> Mailing

We've got some counters on Emails and Mailings that work just fine when a new EmailEvent is created. They're hooked up like so:

  counter_culture [:email, :mailing], column_name: "viewed_count"
  counter_culture :email, column_name: "viewed_count"

But when we run counter_culture_fix_counts on either type of EmailEvent, this happens:

2.1.2 :017 > EmailEvent::Viewed.counter_culture_fix_counts
  Mailing Load (1.2ms)  SELECT  mailings.id, COUNT(email_events.id) AS count, mailings.viewed_count FROM "mailings" LEFT JOIN emails ON mailings.id = emails.mailing_id AND emails.type IN ('EmailEvent::Viewed') LEFT JOIN email_events ON emails.id = email_events.email_id AND email_events.type IN ('EmailEvent::Viewed') GROUP BY "mailings"."id"  ORDER BY "mailings"."id" ASC LIMIT 1000 OFFSET 0
PG::UndefinedColumn: ERROR:  column emails.type does not exist
LINE 1: ...OIN emails ON mailings.id = emails.mailing_id AND emails.typ...

I'll keep chugging on a solution and issue a PR if I come up with anything. But I figured others should know.

Thanks for taking a look at this!

fix_counts does not work with self-referential models

Example:

    Failure/Error: fixed = Company.counter_culture_fix_counts
ActiveRecord::StatementInvalid:
    SQLite3::SQLException: ambiguous column name: companies.id: SELECT  companies.id, COUNT(companies.id) AS count, companies.children_count FROM "companies" LEFT JOIN companies ON companies.id = companies.parent_id GROUP BY "companies"."id"  ORDER BY "companies"."id" ASC LIMIT 1000 OFFSET 0
    # ./lib/counter_culture.rb:118:in `block (2 levels) in counter_culture_fix_counts'
    # ./lib/counter_culture.rb:102:in `each'
    # ./lib/counter_culture.rb:102:in `block in counter_culture_fix_counts'
    # ./lib/counter_culture.rb:62:in `each'
    # ./lib/counter_culture.rb:62:in `counter_culture_fix_counts'
    # ./spec/counter_culture_spec.rb:1333:in `block (3 levels) in <top (required)>'

Touching the counter_cultured model

It would be nice if updating the counters also set the model's updated_at field to the current time, in order to facilitate cache expiration.

Imagine a Category index page listing category names and product counts. These days, it is trivial to perform http caching and/or cache the view using a key that includes the most recent change to the categories.

# controller
fresh_when last_modified: @categories.maximum(:updated_at)

# haml view
- cache ['categories', @categories.maximum(:updated_at)] do
  = the view template

Now, if I add/remove a product or change a product's category, I also need to touch the affected categories, otherwise the category index will be stale. Normally, you would enforce this like so:

belongs_to :category, touch: true

HOWEVER, this is too general, as it will cause the cache to needlessly expire when, for example, I am only editing a product's name or other attribute.

Thus, ideally I would like to be able to say something like:

counter_culture :category, touch: true

Does this sound reasonable? I looked at the source, and I understand that you eventually call rails' update_counters AR method, so the fix would be a little more involved than I initially hoped...

Thanks!
Giuseppe

Generator raises NoMethodError on 4.1.0.rc1

I tried to run generator command, got this error:

$ bundle exec rails g counter_culture Shop menus_count
/Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/generators/actions/create_migration.rb:13:in `migration_file_name': protected method `migration_file_name' called for #<CounterCultureGenerator:0x007fcce2d67b88> (NoMethodError)
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/generators/actions/create_migration.rb:34:in `existing_migration'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/actions/empty_directory.rb:112:in `invoke_with_conflict_check'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/actions/create_file.rb:60:in `invoke!'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/actions.rb:94:in `action'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/generators/migration.rb:34:in `create_migration'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/generators/migration.rb:63:in `migration_template'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/counter_culture-0.1.19/lib/generators/counter_culture_generator.rb:14:in `generate_migration'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `block in invoke_all'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `each'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `map'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `invoke_all'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/group.rb:232:in `dispatch'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/generators.rb:157:in `invoke'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/commands/generate.rb:11:in `<top (required)>'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/activesupport-4.1.0.rc1/lib/active_support/dependencies.rb:247:in `require'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/activesupport-4.1.0.rc1/lib/active_support/dependencies.rb:247:in `block in require'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/activesupport-4.1.0.rc1/lib/active_support/dependencies.rb:232:in `load_dependency'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/activesupport-4.1.0.rc1/lib/active_support/dependencies.rb:247:in `require'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/commands/commands_tasks.rb:135:in `generate_or_destroy'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/commands/commands_tasks.rb:51:in `generate'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
    from /Users/ykiwng/.rvm/gems/ruby-2.1.0/gems/railties-4.1.0.rc1/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

fix_counts fails with error "must provide column_name" if conditional returns nil

counter_culture :category, :column_name => Proc.new {|model| model.special? ? 'special_count' : nil }

If the model above is not special, nil is returned...and then fix_counts yells "must provide column_name". If nil is returned, shouldn't count_fix move on, rather than get stuck on no column_name?

Is there a work around for this?

Using update with _destroy set causes the counter to be decremented by 2

I have two models:

class Resume < ActiveRecord::Base
  has_many :abstracts, :dependent => :destroy
end

and

class Abstract < ActiveRecord::Base
  belongs_to :resume, touch: true
  counter_culture :resume
end

In the resume controller I have:

  before_action :set_resume, only: [:show, :edit, :update, :destroy]
  def update
    respond_to do |format|
      if @resume.update(resume_params)
        # Stuff
      end
    end
  end

 def resume_params
   params.require(:resume).permit(
        :abstracts,
        abstracts_attributes: [:id, :title, :text, :_destroy])
end

When I add a new Abstract the counter goes up correctly but when deleting one through the ResumeController::update method the count decreases by two.

Conditional Column Name Failure

First of all, thanks for running this awesome project!

However, I think I've found a bug in counter_culture on Rails 4.1. It seems that the conditional column_name hack isn't working. In the code sample below, I have put in a totally invalid :column_name value "xxx" to be returned if the model.published? does not return nil.

counter_culture :story,
                  :column_name => Proc.new {|model| 
                          model.published? ? "xxx" : nil
                        },
                  :column_names => {['parts.status = ?', 'published'] => "parts_count"}

When this code runs, I see this in my logs:

 UPDATE `stories` SET `read_count` = COALESCE(`read_count`, 0) + 0 WHERE `stories`.`id` = 27505

So, apparently, returning nil from that block is actually just going with the default name instead of not-counting. Calling fix_counts actually provides correct counts.

Multi-level counter-cache following similar path seem to affect each other

Not sure if this is a bug or user-error. I'll try to illustrate this...think in terms of a flight school with students and instructors.

Account class
belongs_to :user

Rating class
belongs_to :account # the students account

Flight class
belongs_to :account # the instructors account
belongs_to :rating

counter_culture [:account, :user], # the instructor
delta_column: 'total_time',
column_name: "total_time_sum",
column_names: { ["flights.total_time > ?", 0] => "total_time_sum" }

counter_culture [:rating, :account, :user], # the student
delta_column: 'total_time',
column_name: "total_time_sum",
column_names: { ["flights.total_time > ?", 0.0] => "total_time_sum" }

These counters live in the Flight model. There are two users involved in a flight (student and instructor). The students account is associated to the flight through their rating, whereas the instructors account is directly associated with the flight. If they both go out and fly, they both need to update the total_time_sum column in the users table.

[:account, :user] should only affect instructors
[:rating, :account, :user] should only affect students.

However, when I run Flight.counter_culture_fix_counts all users run through both of these methods. In some cases the first method updates the cache to a real value, and the second sets it to 0.0...or visa versa. For example, near the top of the hash is {:entity=>"User", :id=>224, :what=>"total_time_sum", :wrong=>0.0, :right=>59.3} and further down the hash is {:entity=>"User", :id=>224, :what=>"total_time_sum", :wrong=>59.3, :right=>0.0}

I've inspected my models and don't see where anything else might cause this. I'll try to write a spec for this. But, I wanted to reach out and see if you have encountered this, or perhaps my setup is wrong.

Thanks

Bug: changing model twice within the same transaction doesn't increment counter

After some time trying to debug a model whose counter wasn't incrementing in my app, I found a counter_culture bug.

What happens
Counters are not incremented nor decremented when parent elements triggers children #save.

How to reproduce

  • Add a call back in the parent model that changes children
  • Wrap parent model #save call AND any children change within a transaction.

Why does it happen?
I don't know. I've tried to โ€“ but couldn't - fully understand how counter_culture works. But maybe it is incrementing when model is being created and then it decrements back to 0 when model is changed. I'm not sure.

Example:
I've created a Rails app to demonstrate the bug.
Run rake test and see tests failing.
Take a look at test/unit/child_test.rb to understand what's going on.
https://github.com/leods92/counter_culture_after_commit_bug

I'd be glad to further discuss about this issue and help someone solve it.
Also, if you guys can give me a clue of what's causing this problem I can provide a pull request.

And thank you, @magnusvk, for this awesome gem. :)

Using outdated counts when running counter_culture_fix_counts?

counter_culture_fix_counts first loads all the correct counts into memory, then iterates over all instances and compares counts. Now, if in between loading the correct counts and comparing them in the loop, new children were created or destroyed, this count will be off and reset to an incorrect, outdated value.

Maybe we can use an update_all with a JOIN to let the database handle this atomically? Might this also be faster?

We could also put the fetching of each correct count and the corresponding update into a transaction, but then that would slow the whole process way down.

Increment count by an arbitrary function of the many side (product)

I would like if this is currently possible, and if not make a feature request.
If the feature is desirable I may try to implement it.

This will be better explained with an example.

A bug tracker issue has comments.

It is possible to upvote issues by starting a comment with +1, and downvote them by starting it with -1.

I want to keep a running count of the score = upvotes - downvotesof an issue on a table column.

What I would like to write:

class Comment < ActiveRecord::Base
    belongs_to :issue
    counter_culture :issue,
            :column_name => 'issue_score_count',
            :delta => Proc.new {|comment|
                if comment.start_with?('+1')
                  1
                elsif comment.start_with?('-1')
                  -1
                else
                  0
                end
             }
end

class Issue < ActiveRecord::Base
    has_many :products
end

Where :delta is the "feature" I would like.

If this were possible, it would be strictly more general than delta_column, which could be implemented simply as:

:delta => Proc.new {|comment| comment.column_name}

How to properly trigger on update?

I have this in my user.rb:

belongs_to :user
counter_culture :user,
    :column_names => {
        ["goals.completed = 1"] => 'goals_completed_count',
        ["goals.id"] => 'goals_count'
    }

This seems to work fine on create and destroy. On update, I'm not sure how to trigger it. The end result I'm after is knowing how many total goals each user has, and how many of those are completed. In my code above, I'm using "goals.id" just so the counter includes all goals since that's my total goals field. The other one is matching off of the completed field which is a boolean.

BTW, completed is a checkbox and can be set either at creation or when doing an update. I thought I would just manually do an after_update but I can't tell if a record was previously marked completed or not.

This is an awesome gem and does exactly what I want... if I could just figure out how to get it properly setup. I ran the manual update in the console and it properly updated both fields so that part seems setup correctly.

Confusing config format

I understand the need for the column_names config in order to facilitate fast manual updates, but the format made my brain hurt. This seems confusing to me:

:column_names => {
   ["products.product_type = ?", 'awesome'] => 'awesome_count',
   ["products.product_type = ?", 'sucky'] => 'sucky_count'
 }

Wouldn't something like this make more sense?

:column_names =>  [
  :awesome_count => ["products.product_type = ?", 'awesome'] ,
  :sucky_count => ["products.product_type = ?", 'sucky']
]

This is far more readable and clear to me.

If you changed this, you could continue to support both formats by checking if the value passed is an array.

Totals not updating correctly when delta_column is changed through a callback

Thanks for the great gem, it's designed to do exactly what I was looking for: keep a cache column of a sum, rather than just a count.

I have a setup like so:

class Game < ActiveRecord::Base
  has_many :players

  def modify_player_scores
    players.each do |p|
      p.update(score: p.raw_score * 2)
    end
  end
end

class Player < ActiveRecord::Base
  belongs_to :game
  counter_culture :game, :column_name => 'total_score', :delta_column => 'score'

  after_create do
    game.modify_player_scores
  end
end

When a player is created, this triggers a callback to it's parent game that modifies the player. I would expect the cache column to update when the player is changed in this manner, but it does not seem to do that.

Instead, it either ignores the updated value or uses the updated value incorrectly at a later time when another update is called manually.

I forked and made a test illustrating this, and will try to attach a pull request. Should I now make a pull request, or do you want to grab the test from my fork another way? (Forgive me, this is the first time I've tried to share code with an existing repository.)

Also, it's entirely possible that this test is trying to do something that is not the intended behavior. If so, please let me know.

Thank you again for your time.

Doesn't work when conditional criteria changes

I'm trying to keep a counter of the # of targets a given theme has that are NOT completed.

Target.tier != "Completed"

I created the field Theme.active_targets_count successfully.

The relevant section in my target.rb:

belongs_to :theme
counter_culture :theme, :column_name => Proc.new {|model| model.tier != "Completed" ? 'active_targets_count' : nil }

If a Target.tier == "1" and then I run the following:

def complete
    @target.update_columns(completion_date: Time.current, tier: "Completed")
    redirect_to targets_path, :notice => "Target marked complete."
end

The active_targets_count does not decrement.

Am I doing something wrong or is this an issue? Thanks! Love your gem and it's been very handy on other projects.

Enum in model's default scope breaks counter updates

I have a User class with an enum status and a default scope that checks this status:

class User < ActiveRecord::Base 
  enum status: [:active, :suspended, :inactive]
  ...
  default_scope { where status: :active }
  ...

I added a couple counter columns to my users table, and when I try to manually set the values, I get a MySQL error because of the default scope applying the enum in a way that the update doesn't like.

UserLogin.counter_culture_fix_counts
  User Load (0.9ms)  SELECT  users.id, COUNT(user_logins.id) AS count, users.logins_count FROM `users` LEFT JOIN user_logins ON users.id = user_logins.user_id WHERE `users`.`status` = 'active' GROUP BY `users`.`id`  ORDER BY `users`.`id` ASC LIMIT 1000 OFFSET 0
  SQL (0.6ms)  UPDATE `users` SET `users`.`logins_count` = 4 WHERE `users`.`status` = 'active' AND `users`.`id` = 1
Mysql::Error: Truncated incorrect DOUBLE value: 'active': UPDATE `users` SET `users`.`logins_count` = 4 WHERE `users`.`status` = 'active' AND `users`.`id` = 1
ActiveRecord::StatementInvalid: Mysql::Error: Truncated incorrect DOUBLE value: 'active': UPDATE `users` SET `users`.`logins_count` = 4 WHERE `users`.`status` = 'active' AND `users`.`id` = 1
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:423:in `query'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:423:in `block in exec_without_stmt'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:373:in `block in log'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:367:in `log'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:422:in `exec_without_stmt'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:283:in `exec_query'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:466:in `exec_delete'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract/database_statements.rb:111:in `update'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `update'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.1/lib/active_record/relation.rb:327:in `update_all'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/counter_culture-0.1.24/lib/counter_culture.rb:133:in `block (3 levels) in counter_culture_fix_counts'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/counter_culture-0.1.24/lib/counter_culture.rb:120:in `each'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/counter_culture-0.1.24/lib/counter_culture.rb:120:in `block (2 levels) in counter_culture_fix_counts'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/counter_culture-0.1.24/lib/counter_culture.rb:102:in `each'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/counter_culture-0.1.24/lib/counter_culture.rb:102:in `block in counter_culture_fix_counts'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/counter_culture-0.1.24/lib/counter_culture.rb:62:in `each'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/counter_culture-0.1.24/lib/counter_culture.rb:62:in `counter_culture_fix_counts'
    from (irb):16
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands/console.rb:90:in `start'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands/console.rb:9:in `start'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands/commands_tasks.rb:69:in `console'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
    from /Users/jaime/.rvm/gems/ruby-2.1.1/gems/railties-4.1.1/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'

It seems to work when I do something like:

User.unscoped do
  UserLogin.counter_culture_fix_counts
end

which I got from http://stackoverflow.com/a/4759121/1461038

I figured I'd document my solution here in case anyone else has the same problem, or if there is a better solution.

Trigger method when counter (or sum of counters) meet condition?

This is not really an issue of the gem itself (which it has been really useful), but I would like to ask what would be the suggested way of dealing with the following problem I have.

In one of my models (Order) I have several counters that keep track of the number of Ads (Order has_many Ads), depending on their status. So, I have the following in my Ad model:

counter_culture :order, :column_name => Proc.new {|model| model.pending_review? ? 'pending_review_ads_count' : nil }
counter_culture :order, :column_name => Proc.new {|model| model.reviewed? ? 'review_ads_count' : nil }
counter_culture :order, :column_name => Proc.new {|model| model.failed? ? 'fail_ads_count' : nil }
counter_culture :order, :column_name => Proc.new {|model| model.pending? ? 'pending_ads_count' : nil }

I am trying to dinamically change the status of an Order, when some conditions happen with its counters. For example

  • If pending_review_ads_count + failed_ads_count >= ads_count do something.

What would be the best approach of doing this kind of comparison on the counters in order to trigger a specific method?

Float values being trimmed to integers during counter_culture_fix_counts

This hash is returned when running counter_culture_fix_counts.

{:entity=>"User", :id=>263, :what=>"total_time_sum", :wrong=>10.6, :right=>10}.

The DB schema on this column is:
t.float "total_time_sum", default: 0.0, null: false

The total is, in fact, 10.6...so counter_culture seems to be confused about the float value.

multi counter in model

i tried following in my model:

counter_culture :playground, :column_name => Proc.new {|model| model.recognized? ? 'playground_snapshots_recognized_count' : nil }
counter_culture :playground, :column_name => 'playground_snapshots_taken_count'

its working and updating both columns if model.recognized, otherwise updating just taken column. Perfect.

I would like to test it since there is some logic behind. I have been using database cleaner with truncation mode, trying to call model.reload in test but counters are not updated at all.

counter_culture_fix_counts is not correct when the column is a sum

When I run counter_culture_fix_counts, it returns that a column is wrong and should be a sum of 0.0. When, in fact the columns sum is not zero. Also, counter_culture_fix_counts is returning records that it thinks are incorrect, but it is not updating the database...just returning the hash.

Rails 4: DEPRECATION WARNING

I updated to from 0.1.14 ~> 0.1.16 and receive now the following deprecation warning with Rails 4.

DEPRECATION WARNING: #connection is deprecated in favour of accessing it via the class.

I tried to run the counter_culter tests on my local machine with rake and rspec, but it looks like there is a loop somewhere. (ruby 2.0)

Excerpt from the console output:

D, [2013-10-07T16:44:40.118517 #38558] DEBUG -- :    (1.2ms)  commit transaction
D, [2013-10-07T16:44:40.119292 #38558] DEBUG -- :    (0.1ms)  begin transaction
D, [2013-10-07T16:44:40.121151 #38558] DEBUG -- :   SQL (0.5ms)  INSERT INTO "simple_dependents" ("created_at", "simple_main_id", "updated_at") VALUES (?, ?, ?)  [["created_at", Mon, 07 Oct 2013 23:44:40 UTC +00:00], ["simple_main_id", 3610], ["updated_at", Mon, 07 Oct 2013 23:44:40 UTC +00:00]]
D, [2013-10-07T16:44:40.122453 #38558] DEBUG -- :   SimpleMain Load (0.1ms)  SELECT "simple_mains".* FROM "simple_mains" WHERE "simple_mains"."id" = ? ORDER BY "simple_mains"."id" ASC LIMIT 1  [["id", 3610]]
D, [2013-10-07T16:44:40.124705 #38558] DEBUG -- :    (1.6ms)  commit transaction
D, [2013-10-07T16:44:40.128017 #38558] DEBUG -- :   SQL (2.0ms)  UPDATE "simple_mains" SET "simple_dependents_count" = COALESCE("simple_dependents_count", 0) + 1 WHERE "simple_mains"."id" = 3610
D, [2013-10-07T16:44:40.128639 #38558] DEBUG -- :    (0.2ms)  begin transaction
D, [2013-10-07T16:44:40.131126 #38558] DEBUG -- :   SQL (0.6ms)  INSERT INTO "simple_dependents" ("created_at", "simple_main_id", "updated_at") VALUES (?, ?, ?)  [["created_at", Mon, 07 Oct 2013 23:44:40 UTC +00:00], ["simple_main_id", 3610], ["updated_at", Mon, 07 Oct 2013 23:44:40 UTC +00:00]]
D, [2013-10-07T16:44:40.132465 #38558] DEBUG -- :   SimpleMain Load (0.1ms)  SELECT "simple_mains".* FROM "simple_mains" WHERE "simple_mains"."id" = ? ORDER BY "simple_mains"."id" ASC LIMIT 1  [["id", 3610]]
D, [2013-10-07T16:44:40.134285 #38558] DEBUG -- :    (1.3ms)  commit transaction
D, [2013-10-07T16:44:40.136665 #38558] DEBUG -- :   SQL (1.4ms)  UPDATE "simple_mains" SET "simple_dependents_count" = COALESCE("simple_dependents_count", 0) + 1 WHERE "simple_mains"."id" = 3610
D, [2013-10-07T16:44:40.136985 #38558] DEBUG -- :    (0.1ms)  begin transaction
D, [2013-10-07T16:44:40.139417 #38558] DEBUG -- :   SQL (0.9ms)  INSERT INTO "simple_dependents" ("created_at", "simple_main_id", "updated_at") VALUES (?, ?, ?)  [["created_at", Mon, 07 Oct 2013 23:44:40 UTC +00:00], ["simple_main_id", 3610], ["updated_at", Mon, 07 Oct 2013 23:44:40 UTC +00:00]]
D, [2013-10-07T16:44:40.140599 #38558] DEBUG -- :   SimpleMain Load (0.1ms)  SELECT "simple_mains".* FROM "simple_mains" WHERE "simple_mains"."id" = ? ORDER BY "simple_mains"."id" ASC LIMIT 1  [["id", 3610]]
D, [2013-10-07T16:44:40.142350 #38558] DEBUG -- :    (1.2ms)  commit transaction
D, [2013-10-07T16:44:40.144588 #38558] DEBUG -- :   SQL (1.5ms)  UPDATE "simple_mains" SET "simple_dependents_count" = COALESCE("simple_dependents_count", 0) + 1 WHERE "simple_mains"."id" = 3610
D, [2013-10-07T16:44:40.145144 #38558] DEBUG -- :    (0.1ms)  begin transaction
D, [2013-10-07T16:44:40.147456 #38558] DEBUG -- :   SQL (0.9ms)  INSERT INTO "simple_mains" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", Mon, 07 Oct 2013 23:44:40 UTC +00:00], ["updated_at", Mon, 07 Oct 2013 23:44:40 UTC +00:00]]
D, [2013-10-07T16:44:40.154149 #38558] DEBUG -- :    (6.1ms)  commit transaction

Terminating counter_culture_fix_counts midway through

For any reasonably sized table, counter_culture_fix_counts will taken a non-trivial amount of time to run.

In keeping with the mantra of disposability required when using services such as Heroku (as I do), I was wondering: If a counter_culture_fix_counts is killed halfway through, do we lose all the fixed counts?
I.e. if it is killed before completion and I restart it immediately, will be back to square one, or do you expect it to complete quicker the second time (since some set of the incorrect counts will already have been fixed)?

Having trouble with many-to-many association

Hi - I'd love to use this gem, but I'm having trouble using it for a many-to-many association.

Here's the setup:
Attendee <--> Access <--> Meeting

Attendee model has_many :accesses and has_many :meetings, :through => :accesses
Access model belongs_to :attendee and belongs_to :meeting
Meeting model has_many :accesses and has_many :attendees, :through => :accesses

I'd like to keep a counter of Attendees for each Meeting
The Attendee model has:
counter_culture [:accesses, :meetings] #[:access, :meeting]

I set up the integer column attendees_count on Meeting just like the example.

When I expect the counter to be updated, I get this error:
undefined method `attendee_id_changed?' for #Attendee:0x007fd03246ac30

Can you help? Thanks, Justin

Reseting counters

How to reset counters for separate object or for objects matching some query? For example where(deleted: false, hidded: false)

Manually filling in dynamic column name based on joined model

OK, so I have a situation where an Article has_many Tags, and a Tag has_many Articles, through a join table that belongs_to both of them. That's where this code is:

class ArticlesTag < ActiveRecord::Base
  belongs_to :article
  belongs_to :tag

  counter_culture :tag, column_name: "articles_count"
  counter_culture :tag, column_name: Proc.new{ |model| model.article.recent? ? 'recent_articles_count' : nil }

As you can see, I'm trying to store both the number of articles associated with a tag, and the number of "recent" articles. The problem here comes up when I try to populate the count columns in the Tag table using counter_culture_fix_counts:

Must provide :column_names option for relation [:tag] when :column_name is a Proc; you may skip this relation with :skip_unsupported => true

But I can't figure out how to properly configure that option. The condition that makes an article recent is on the article table itself, not the join table where all the counter_cache code is going. If I add an option like:

column_names: {
  ["articles.created_at > ?", 30.days.ago] => 'recent_articles_count'
}

I just get an error that there is no such column 'articles.created_at', since the articles table isn't being joined in when it tries to run the counter_culture_fix_counts command.

Issues in testing

The counters doesn't seem to update well in test environment.

Let's go with three models User, Product, and Purchase, where a user has_many products through purchases. User is counting purchases.

When I run @user.products.push(@Product), it seems to update the counter just fine.
However, @user.purchases.create(product: @Product) does not update the counter. I have to run Purchase.counter_culture_fix_counts in order to get the test passing.

I have to use 'create' instead of 'push' for various reasons. Using create works fine in real use cases, but it doesn't work in test environment.

Running counter_culture_fix_counts in test is not a big deal, but it would be good to get it working without running the fix method.

Error when deleting record

For example (see code below)...when deleting a rating that is associated with the account, the conditional for counter_culture complains with "undefined method `ratings' for #<Rating:..."

rating.rb
belongs_to :account
counter_culture :account, column_name: Proc.new {|account| account.ratings.active.present? ? 'active_ratings_count' : nil }
counter_culture :account, column_name: Proc.new {|account| account.ratings.present? ? 'ratings_count' : nil }

account.rb
has_many :ratings, dependent: :destroy

Carrierwave with amazon s3 not work with counter_culture gem

If you create model like this

class UploadTest < ActiveRecord::Base

  belongs_to :category

  attr_accessible :category_id, :something

  mount_uploader :something, PhotoUploader

  counter_culture :category
end

with uploader connected to s3 (fog and carrierwave-aws backends have same behavior) after updating file only file name in database is updated, but new file on s3 is not uploaded (old file stays on s3). This issue only on updating file, creating new object works ok.

I've created same issue in carrierwave project.

undefined method foreign_key

I'm trying to setup counter_culture on a rails 3.0.11 project which I've got a relationship between two models like so:

class Parish < ActiveRecord::Base
  belongs_to :incumbent, :class_name => "Person"
  counter_culture :incumbent, :column_name => "parishes_count"
...
class Person < ActiveRecord::Base
  has_many :parishes, :foreign_key => :incumbent_id
...

When I update the parish with a new incumbent I get this error:

undefined method `foreign_key' for #<ActiveRecord::Reflection::AssociationReflection:0x0000000721b310>

Conditional Counter Cache not updating when condition field changes

Could there be an option to have the counter cache updated every time a model is saved? With the example below, when the name field is updated, thereby changing the special status, special_count is not updated.

class Product < ActiveRecord::Base
   belongs_to :category
   counter_culture :category, :column_name => Proc.new {|model| model.special? ? 'special_count' : nil }

    def special?
        name.include("Cool") || name.include("Groovy")
    end
end

The problem looks like it's on line 193 of lib/counter_culture.rb.

By the way, I found your gem on the comments section of the railscasts counter cache episode. Thanks for putting this together.

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.