Model Association Problems

55 views
Skip to first unread message

Paul

unread,
Oct 16, 2014, 12:31:03 PM10/16/14
to ceq...@googlegroups.com
Hi all,

I'm starting a RoR3 project with Cassandra Database using Cequel 1.4.1, a Ruby ORM for Cassandra. It's a great ORM and easy to use because of
it's ActiveRecord-like coding and model association style. But as i go on with my development using model associations i encountered some errors and finding it hard to find a right solution for my problem.

My problems encountered with the given model association are:

class User
  include Cequel::Record

  has_many :carts
  has_many :cart_items

  key :id, :uuid, auto: true
  column :email, :text
  column :encrypted_password, :text
  timestamps
end

class Cart
  include Cequel::Record

  belongs_to :user
  has_many :cart_items

  key :id, :uuid, auto: true
  column :name, :text
  timestamps
end

class Product
  include Cequel::Record

  has_many :cart_items

  key :id, :uuid, auto: true
  column :name, :text
  timestamps
end

class CartItems
  include Cequel::Record

  belongs_to :user
  belongs_to :cart
  belongs_to :product
end

1. For User and Cart model, the association between both the model is required upon creation of the data. I want to create either the User or the Cart first and set the connection for the both at a later time. I also tried putting this code in Cart model but still doesn't work: validates :user_id, presence: false

2. For CartItems model, running rake cequel:migrate outputs an error saying Cequel::Record::InvalidRecordConfiguration: Can't declare more than one belongs_to association.


I hope someone can help me on this, or can give me a better solution or idea on what i'm trying to achieve here using Cassandra database. Thanks!

Matthew A. Brown

unread,
Oct 17, 2014, 8:33:06 PM10/17/14
to Paul, ceq...@googlegroups.com
Hey Paul,

Sorry to keep you waiting on this. Both of the challenges you've come across stem from the fact that the has_many/belongs_to relationship in Cequel is a bit different than it is in ActiveRecord. In particularly, it encodes a parent-child relationship, rather than an arbitrary one-to-many relationship as in ActiveRecord.

For that reason, any Cart that's created needs to know what its parent (User) is; the user_id is actually part of the Cart's primary key (this is automatically handled by the belongs_to declaration in Cequel). Since the User doesn't have any parent, you can create a User first, and then create the user's carts. But you can't create a Cart without a User.

As for the second question, because belongs_to is a parent-child relationship, you can only have one belongs_to in a model class; it can only have one parent. You can have as many has_many declarations as you'd like, though.

So, here's how I'd structure your classes, off the top of my head:

class User
  include Cequel::Record

  has_many :carts

  key :id, :uuid, auto: true
  column :email, :text
  column :encrypted_password, :text
  timestamps
end

class Cart
  include Cequel::Record

  belongs_to :user
  has_many :cart_items

  key :id, :uuid, auto: true
  column :name, :text
  timestamps
end

class CartItem
  include Cequel::Record

  belongs_to :cart
  key :id, :uuid, auto: true
  column :product_id, :uuid, index: true

  def product
    @product ||= Product.find(product_id)
  end
end

class Product
  include Cequel::Record

  key :id, :uuid, auto: true
  column :name, :text
  timestamps

  def cart_items
    @cart_items ||= CartItem.where(product_id: id)
  end
end

Note that the association between CartItems and Products is hand-rolled—Cequel does not currently have a mechanism for describing relationships between models that are not encoded in the primary key. I have thought it would be helpful to provide a references_one/referenced_by functionality to Cequel, although I have not seen a tremendous amount of demand for it, so I haven't made it a priority.

Let me know if that helps and if anything needs clarification!
Mat

--
You received this message because you are subscribed to the Google Groups "Cequel" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cequel+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages