0

I have a customer model, a merchant model and a transactions model. Customers can make transactions to merchants and merchants can make transactions to customers as well. Eventually, I'd like to query things like:

  1. All transactions made by a customer
  2. All transactions made by a merchant
  3. All of customer X's transactions to merchant Y (and vice versa)
  4. Optional: final all transactions with a certain tag first, and then find all associated merchants and customers related to those transactions. This is a nice-to-have feature, but if it's too complicated to explain in an answer then don't worry about it

So conceptually how should I create associations for each of these models? Like Customers has_many :merchants, through: :transactions (and vice versa)? or use polymorphic associations? etc etc.

Thanks a lot for your help!!!

tereško
  • 58,060
  • 25
  • 98
  • 150
Hongyi Li
  • 1,059
  • 2
  • 11
  • 19
  • by the way I use ActiveJdbc as my ORM. it's very similar to activerecord, so any solutions using activerecord will be awesome. but if you know how to do so using activejdbc then even better. Thanks :) – Hongyi Li Aug 02 '14 at 01:04

2 Answers2

2

OK, the suggestion by @infused looks great. Here is the same in ActiveJDBC

First define models:

public class Customer extends Model {}
public class Merchant extends Model {}
public class Transaction extends Model {}

Second, create tables:

CUSTOMERS:

id | first_name | last_name | etc

MERCHANTS:

id | name | address1 | etc

TRANSACTIONS:

id | customer_id | merchant_id | tag | etc

find all of a customer's transactions:

customer.getAll(Transaction.class);

To find all of a merchant's transactions:

merchant.getAll(Transaction.class);

Find all of Customer #1's transactions for Merchant #25

customer = Customer.findById(1);
customer.get(Transaction.class, "merchant_id = ?", 25);

Find all of Merchant #1's transactions for Customer #8

 merchant = Merchant.findById(1);
 merchant.get(Transaction.class, "customer_id = ?", 8);

Find all Transactions by a tag (assuming tag is a string field):

transactions = Transaction.where("tag = ?", "best-seller");

Find all Merchants with Transactions tagged with 'best-seller':

transactions = Transaction.where("tag = 'best-seller'").include(Merchant.class);
//iterate over transactions, and get a merchants:
transactions.get(i).getAll(Merchant.class)

This approach will run only 2 SQL queries, and is very fast.

I hope this helps

ipolevoy
  • 5,432
  • 2
  • 31
  • 46
1

Conceptually, the Transaction model joins Customer and Merchant, so:

class Customer < ActiveRecord::Base
  has_many :transations
  has_many :merchants, through: :transactions
end

class Merchant < ActiveRecord::Base
  has_many :transactions
  has_many :customers, through: :transactions
end

class Transaction < ActiveRecord::Base
  belongs_to :customer
  belongs_to :merchant
end

To find all of a customer's transactions:

customer.transactions

To find all of a merchant's transactions:

merchant.transactions

Find all of Customer #1's transactions for Merchant #25

customer = Customer.find(1)
customer.transactions.where(merchant_id: 25)

Find all of Merchant #1's transactions for Customer #8

merchant = Merchant.find(1)
merchant.transactions.where(customer_id: 8)

Find all Transactions by a tag (assuming tag is a string field):

transactions = Transaction.where(tag: 'best-seller')

Find all Merchants with Transactions tagged with 'best-seller':

merchants = Merchant.includes(:transaction).where(transaction: {tag: 'best-seller'})

Find all Customer with Transations tagged with 'best-seller':

customers = Customer.includes(:transation).where(transaction: {tag: 'best-seller'})
infused
  • 24,000
  • 13
  • 68
  • 78
  • thank you so much @infused for this detailed answer! Quick question: using the models you specified, under what circumstances would I need to use polymorphic associations? – Hongyi Li Aug 02 '14 at 01:10
  • @HongyiLi, I don't see any reason to use polymorphic associations given your example. Polymorphic associations are for when you want a single association between different types of things. For example, you might want to associate a Note model with both a Merchant and a Customer, so that a Merchant has many notes and a Customer has many notes. That note association could be polymorphic, so a Note could belong to either a Customer or a Merchant. – infused Aug 02 '14 at 01:17