Ohad Dahan


870 Experience
6 Lessons Completed
0 Questions Solved


Posted in Multi tenant - will it help?

Here is the case , I got users and a few other models , most of them end up doing some action with one main table that contains around 15M rows.

I have an indexed foreign key between the main table and the user model , and plently of specific columns indexes to speed up various queries.

I recently added an Ajax-DataTable view which queries this table for each change , this caused a huge bottleneck in the application.

I think this is happening due to too many calls using the same table.
I'm thinking of migrating the existing application to a multi-tenant strucutre , where each user will have its own main table.
Thus having less locks on the same table.

Anyone have any expirience with anything similar?

Posted in Checking for uniqueness

You can create a custom validations to do anything you need (it runs arbitrary code you place in it)
Just make sure it's efficient with proper indexes etc.

I'm not sure if I got the model perfectly but if you inherent the details.
As in , pass the Schedule the room_id and than you can run a simple unique index on it without going through up/down relations.

Yes, you'll have an extra column (room_id on Schedule) you might not need and can get by association , but that's not a large price for simpler design.

I didn't understand the problem once you change the iterator.
Are you having any issue with <% user_stock.symbol %> or anything similar?

  1. Add prints from inside the view <% puts "user_id = #{@user.id} | current_user.id = #{current_user.id} | user_stock = #{user_stock.inspect}" %> to see what is the content in the view.

  2. Your user model should have user_stocks association on it, did you create a foreign key reference?

  3. Yeah , where usualy works on some ActiveRecord types. The various find* methods are actually wrappers for where. For example find_by https://apidock.com/rails/v4.0.2/ActiveRecord/FinderMethods/find_by , although I'm missing a limit(1) in those calls , that bothers me a little bit since if you know that you take the first only than you should also limit the SQL call.

Try #1 , to understand what's going on , the inconsistency must be in one of the 3 variables hence , start exploring them. puts and inspect are your friends :)

The easiest way is to mimmic the flow in your console.
Check UserStock.last and compare its details to the one you're trying to find after the second time.

BTW a few things that will make your code cleaner (in my personal opinion)

I would replace set_user_stock by:

def set_user_stock
       @user_stock= @user.user_stocks.find_by( id: params[:id]) 
         if @user_stock.nil?
          # do something , for example:
             flash[:danger]= 'msg'
             redirect_to 'path' and return

This will also remove the need for the if @user.id condition since if some other user tries to touch another user stock , he will get redirected.

No need to define find_by_ticker simply use Model.find_by( key_name: value) , it will return the model or nil.
Also , you can add a unique index + validation on ticker_symbol (or ticker_symbol && user_id which make it easier to search/validate the checks you do.

Is this a typo?
<% if @user.id = current_user.id %>
You're assigning to @user.id and not comparing ==.

Posted in Shrine vs. Carrierwave

I noticed in the screencasts that the first one is on Carrierwave , but later on they're on all Shrine.
I really like https://github.com/diogob/carrierwave-postgresql (not sure if it supports Shrine) hence I go for Carrierwave.

What am I missing?

Posted in Jquery destroy seems to fire twice.

I think the issue is that you're destroying @line_item but in your redirect_to you're using @line_item.cart_id , that doesn't seem right.

Try to store the URL / id / cart you want to redirect to in some variable , and after the destroy use that to redirect_to.

Posted in Are there any up to date tutorials for jquery-sortable?

Chris , you're creating an N+1 query with your code by calling find inside an iterator.
I think the logic can change to calling Takitem.find( @items ) and than use Active-Import gem to to a bulk update on all items.
That will be 2 database calls instead of @items.size * 2 (a find and update per iteration).

I recommend using RubyMine , it's not free but worth the money.
Especially if you're taking Ruby/Rails as a serious job.
They also have a pretty good vim mode (coming from a vim only guy).

Posted in Recommended Gems - share them here :)

Most of my recommendations are performance oritented but I'll be happy to hear about Gems that can help in other domains.

  1. PGHero https://github.com/ankane/pghero , great to keep track of your database , get index recommendations etc.

  2. Scout Gem/Addon (Heroku , don't know how/if they work outside) of it , again great to keep track of N+1 issues , memory spikes and more.

  3. memory_profiler https://github.com/SamSaffron/memory_profiler , great tool to analyze and compare your memory footprint.

  4. Typehoeus https://github.com/typhoeus/typhoeus , multi-threading HTTP/HTTPS/SOCKS request. VERY easy to use for anything you need. Highly recommended.

  5. Ox https://github.com/ohler55/ox , THE BEST XML parser for Ruby. Saved my life :)

  6. Oj https://github.com/ohler55/oj , same author as Ox , probably the best JSON parser too.

  7. ActiveRecord-Import https://github.com/zdennis/activerecord-import , bulk INSERT / UPDATE operations. Can save a HUGE amount of time.

  8. bootstrap_sb_admin_base_v2 https://github.com/dreamingechoes/bootstrap_sb_admin_base_v2 , a Bootstrap based admin layout not the prettiest but works well and is very easy to setup.

Posted in Optimizing Queries in Service Objects

I'm not sure that I follow , can you write the query you warn from?

Posted in Optimizing Queries in Service Objects

select was mentioned when you still want to fecth ActiveRecord while pluck returns an array.
If you want to limit the size , use limit as I suggested.

If you want to minimze your memory footstamp Model.where( condition ).select(:id) should be smaller thatn Model.where( condition ) while Model.where( condition ).pluck will be the smallest ( pluck also receive attribute names like Model.where( condition ).pluck(:id) ).

Note in the link you provided:
Almost always, you'll want to use where **rather** than select. So, when might you use select? Well you'd use it (**often in conjunction with where**) when you want to filter a relatively small number of records based on some ruby conditions that would be reasonably hard to translate to SQL.

I never said you should use select instead of where but ONLY in conjunction , I actually urge to always use limit to avoid corner cases blowing up your machine memory.

Posted in Optimizing Queries in Service Objects

  1. If you have more than one result but always take first and you don't sort not only that it might be inconsistent , you're pulling data you don't need. Add limit(1) on the query.

  2. Since you're only looking for id anyhow , don't load the entire ActiveRecord use select and pluck to to improve your memory and runtime performance.

  3. Can you add a course_id indexed foreign key to CourseStep model? Than you will be able to query CourseStep.where( course_id: order.course_id , position: 1 ).limit(1).take.pluck(:id).first

Posted in Best approach for combining Rails and Javascript

There is a Rails based Trello clone available on GitHub https://github.com/somlor/kanban .

logo Created with Sketch.

Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

© 2020 GoRails, LLC. All rights reserved.