5

I have 2 tables. I use table prefix x_.

  1. User (table x_users)
  2. Comment (table x_comments)

I want to find out total count after inner join.

This query works fine.

User.joins(:comments).where(x_comments: {something: 1}).count

How can I remove x_ from where condition to make this call generic?

Models

class User < ActiveRecord::Base
    has_many :comments, dependent: :destroy
end

class Comment < ActiveRecord::Base
    attr_accessible :something
    belongs_to :user
end
geek_guy
  • 607
  • 1
  • 5
  • 17
  • Is `User.joins(:follows).where(follows: {something: 1}).count` not working? Your users' association is with `follows`, so it should work. – RAJ Apr 11 '15 at 08:38
  • Post your models too – RAJ Apr 11 '15 at 09:03
  • 1
    You can use `Comment.table_name =>` instead. – BroiSatse Apr 11 '15 at 09:10
  • @RAJ : Updated models and added class definitions. – geek_guy Apr 11 '15 at 09:13
  • @BroiSatse : That works. Is it a proper rails way or work around? Thanks. – geek_guy Apr 11 '15 at 09:17
  • Similar questions: https://stackoverflow.com/questions/36546960/joins-and-where-request-on-association-with-custom-table-name, https://stackoverflow.com/questions/4103677/activerecordrelation-cannot-use-named-association-in-where-clause-of-join, https://stackoverflow.com/questions/45947285/rails-using-join-with-custom-named-associations. Unfortunately none explains why this is like this. – GuiGS May 15 '19 at 14:36

2 Answers2

1

As @BroiSatse already mentioned, You can use ActiveRecord::Base.table_name to set the table name explicitly in a model and to get the table name in a query for genericity.

You query would be:

User.joins(:comments).where(Comment.table_name: {something: 1}).count

Setting a table name explicitly:

class Comment < ActiveRecord::Base
  self.table_name = "x_comments"
end

You can override the table_name method like this:

class Comment < ActiveRecord::Base
  def self.table_name
    "x_" + super
  end
end
Comment.table_name # => "x_comments"
Sharvy Ahmed
  • 7,247
  • 1
  • 33
  • 46
0

Consider writing your conditions as scopes and let ActiveRecord handle the table aliasing for you.

class User < ActiveRecord::Base
  has_many :comments, dependent: :destroy

  def self.for_comment_something(foo)
    joins(:comments).
    merge(Comment.for_something(foo))
  end
end

class Comment < ActiveRecord::Base
  attr_accessible :something
  belongs_to :user

  def self.for_something(foo)
    where(something: foo)
  end 
end

Documentation for ActiveRecord::Relation#merge is here.

Put it all together like

User.for_comments_something(1).count
messanjah
  • 8,977
  • 4
  • 27
  • 40