开发者

CakePHP transparent saving of unique data

开发者 https://www.devze.com 2023-03-10 22:28 出处:网络
I have models Person and Phone/Email with HABTM relationship. After some pain I found out, that my life is easier, when I break HABTM into: Person hasMany PeoplePhone, Phone hasMany PeoplePhone, Peopl

I have models Person and Phone/Email with HABTM relationship. After some pain I found out, that my life is easier, when I break HABTM into: Person hasMany PeoplePhone, Phone hasMany PeoplePhone, PeoplePhone belongsTo (Person,Phone). Well, I don't need any help with this :-) now, my problem is different:

Before I can pair Person with his Phone or Email, I need to save this Phone/Email and then get its ID.

Now I wo开发者_如何转开发uld like to save only unique Phones and unique Emails, so I have created this method in app_model.php:

function saveUnique($data = null, $unique_fieldname = null)
{
    if (! $data) { return false; }
    if (! $unique_fieldname) { return false; }

    $id = $this->field('id', array($unique_fieldname => $data[$this->name][$unique_fieldname]));

    if ($id)
    {
        $this->read(null, $id);
    }
    else
    {
        $this->create();
        $this->set($data);
        if (! $this->validates()) { return false; }
        if (! $this->save()) { return false; }
    }        
    return true;
}

It seems to work, but I am all new to CakePHP. How would CakePHP guru solve this function/method?

Thank you very much for your time.

-Petr


If I were you, I would stick with default Cake functionality rather than what you are doing. All of this functionality is built into Cake, so why reinvent the wheel?

First, HABTM relationships already work as you have broken them out. You can access the join models by adding with in your model associations. This should give you access to the intersection table data.

$hasAndBelongsToMany =  array(
    'Phone' => array(
        'className'              => 'Phone',
        'joinTable'              => 'persons_phones',
        'foreignKey'             => 'person_id',
        'associationForeignKey'  => 'phone_id',
        'unique'                 => false,
        'with'           => 'PersonsPhones'
    )
);

As far as your unique phone and email requirements go, why not use Cake's built in validation to do the checking for you? That way, you just call the save function and then Cake will do all the checking for you.

For instance, if a person only has one email address, then do this in the person model. This will validate that the input is an email address and that it is a unique email address in the database. You can do this validation with any field and build custom validation rules with ease.

public $validate = array(
    'email' => array(
        'email' => array(
            'rule' => 'email',
            'message' => 'You must enter an email address.'
        ),
        'isUnique' => array(
            'rule' => 'isUnique',
            'message' => 'An account with this email address already exists.'
        )
    )
);

I take it that there is a reason for why you would use HABTM for an email address. Normally, people would not share email addresses, so hasMany would probably be a better relationship. I can see it working for phone as people do share phone numbers frequently. I say this so that you are sure that HABTM is the relationship you really want to use.


I've only been using CakePHP for a couple months but I would implement it a little different.

I'd add a UNIQUE index on person_id & email_id in my PeopleEmail table (do the same thing in PeoplePhone). This way we're not accidentally saving duplicate data, our physical schematic prevents duplicate records before they're even stored.

Now we just have to keep an eye out for the SQL error being thrown. I haven't dug too deep into this aspect of Cake yet but I do know the base AppModel class has an onError() method that may provide useful in this regard.

0

精彩评论

暂无评论...
验证码 换一张
取 消