Saving HABTM with extra fields?
HABTM is over-sold. A lot of the times it fails to meet the needs, such as when you have additional data to store. You'll be better off to do a hasMany/belongsTo relationship between the models.
Taken from the CakePHP Book:
What to do when HABTM becomes
complicated?By default when saving a
HasAndBelongsToMany relationship, Cake
will delete all rows on the join table
before saving new ones. For example if
you have a Club that has 10 Children
associated. You then update the Club
with 2 children. The Club will only
have 2 Children, not 12.Also note that if you want to add more
fields to the join (when it was
created or meta information) this is
possible with HABTM join tables, but
it is important to understand that you
have an easy option.HasAndBelongsToMany between two models
is in reality shorthand for three
models associated through both a
hasMany and a belongsTo association.
In your case I would suggest making a LineItem
model and joining everything that way:
Order
hasManyLineItem
LineItem
belongsToOrder
,Product
How to save extra fields in Rails using has_and_belongs_to_many
Note the following is for Rails v2
script/generate model Movie id:primary_key name:string
script/generate model Actor id:primary_key movie_id:integer celeb_id:integer cast_name:string cast_type:string
script/generate model Celeb id:primary_key name:string
model/movie.rb
class Movie < ActiveRecord::Base
has_many :actors
has_many :celebs, :through => :actors
end
model/celeb.rb
class Celeb < ActiveRecord::Base
has_many :actors
has_many :movies, :through => :actors
end
model/actor.rb
class Actor < ActiveRecord::Base
belongs_to :movie
belongs_to :celeb
end
Test the associations with the ruby rails console in the application folder
>script/console
>m = Movie.new
>m.name = "Do Androids Dream Of Electric Sheep"
>m.methods.sort #this will list the available methods
#Look for the methods 'actors' and 'celebs' - these
#are the accessor methods built from the provided models
>m.actors #lists the actors - this will be empty atm
>c = Celeb.new
>c.name = "Harrison Ford"
>m.celebs.push(c) #push Harrison Ford into the celebs for Blade Runner
>m.actors #Will be empty atm because the movie hasnt been saved yet
>m.save #should now save the Movie, Actor and Celeb rows to relevant tables
>m.actors #Will now contain the association for
#Movie(id : 1, name : "Do Androids..") - Actor(id : 1, movie_id : 1, celeb_id : 1) -
#Celeb(id : 1, name : "Harrision Ford")
>m = Movie.new #make a new movie
>m.name = "Star Wars"
>m.celebs.push(c) #associated the existing celeb with it
>m.save
>movies = Movie.all #should have the two movies saved now
>actors = Actor.all #should have 2 associations
>this_actor = Actor.first
>this_actor.cast_type = "ACTOR"
>this_actor.save
Then you'll probably want to check out Ryan Bates' Railcasts http://railscasts.com #47 (Two Many-to-Many), and #73, #74, #75 (Complex forms parts 1-3).
There's an updated version of the many-to-many form code on the webpage for #75.
Add extra field in Rails habtm joins
Instead of HABTM you'd use has_many
and has_many :through
.
class User < ActiveRecord::Base
has_many :memberships
has_many :team, through: :membership
end
class Membership < ActiveRecord::Base # This would be your old 'join table', now a full model
belongs_to :user
belongs_to :team
end
class Team < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
end
Cakephp save extra attribute in HABTM relation
Don't use HABTM
The simplest way to handle has-and-belongs-to-many relations with extra attributes is to obey this rule:
When a link table has more than 2 fields: make it a model
That means convert this relation:
Theme <-habtm-> Color
Into:
Theme <-hasmany- ThemeColor
ThemeColor -belongsTo-> Color
ThemeColor -belongsTo-> Theme
This gives you more control, and simpler code/logic. It's still possible to use a habtm relation when it suits you, and not when it doesn't.
The data structure when saving would then be:
array(
'Theme' => array(...),
'ThemeColor' => array(
array('color_id' => x, 'preview' => y),
...
)
)
There's more detailed notes on this in the documentation.
CakePHP: habtm with join table having an extra field
In your case, HABTM is not the correct association to use. You should be using the hasMany through association.
The fundamental change is that you need a third model based on your product_guest table.
Create these relationships:
- Product hasMany ProductGuest
- Guest hasMany ProductGuest
- ProductGuest belongsTo Product
- ProductGuest belongsTo Guest
CakePHP defining additional fields in HABTM/ManyToMany relationship?
if you want to have additional data in HABTM, use 2 hasMany relationships instead. So if A HABTM B, then set it up as: A hasMany A_B, B hasMany A_B, A_B belongsTo A, A_B belongsTo B. AFAIK, Cake support for HABTM is not very flexible.
Related Topics
Laravel 5.3 Withcount() Nested Relation
Unescape or HTML Decode in Twig (PHP Templating)
Why Does PHP Not Complain When I Treat a Null Value as an Array Like This
What Is a Good Method to Sanitize the Whole $_Post Array in PHP
When and Why Should $_Request Be Used Instead of $_Get/$_Post/$_Cookie
Chart.Js - Getting Data from Database Using MySQL and PHP
PHP Array VS [ ] in Method and Variable Declaration
What Is the Postman-Token Header Attribute in Generated Code from Postman
Alternative to Money_Format() Function
What Does the Dot-Slash Do to PHP Include Calls
PHP - How to Implement Password Reset and Token Expiry
How to Create a New Joomla User Account from Within a Script
Can't Execute PHP Script Using PHP Exec