简体   繁体   中英

Eloquent Relationships

Long story short: I'm building a "privacy" page where uses can chose what shows up and what does not show up on their profiles.

I am considering having a 1:m table user:privacy and just have entries for the keys they want private. If they don't exist they are public. Hope this makes sense.

Table would be user_privacy and will have 3 columns: id, user_id, privacy_key (string, ie email/phone/cell/etc)

Is there a way to simple query by the keys i will define that i can run to determine if the user has a key or not or do i have to go extra lengths to add a function to the user model to do this (trying to avoid, love the magic-ness of eloquent)

Basically i want to have a condition that sounds like "if ($user->privacy->email or $user->privacy->phone)"

Thanks and hope i was clear enough, lol

You could add a function to your user model:

public function isPrivate($attribute){
    $privacyAttribute = $this->privacy->first(function($model) use ($attribute){
        return $model->key == $attribute;  // key being the column in the privacy model
    });
    return !is_null($privacyAttribute);
}

And then do your if statement this way:

if ($user->isPrivate('email') or $user->isPrivate('phone'))

Or a different implementation (usage is the same)

private $privacyAttributes = null;

public function isPrivate($attribute){
    if($this->privacyAttributes == null){
        $this->privacyAttributes = $this->privacy()->lists('key');
    }
    return in_array($attribute, $this->privacyAttributes);
}

User Model header:

/**
 * Class User
 * @package Interallmas
 */
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {

/**
 * @var null|array
 */
protected $privacy_keys = NULL;

Privacy Relationship:

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function privacy() {
        return $this->hasMany('Interallmas\Privacy');
    }

Privacy functions:

/**
     * @return bool
     */
    public function privacy_initialized() {
        return ($this->privacy_keys !== NULL);
    }

    /**
     * @return void
     */
    public function initialize_privacy() {
        if (!$this->privacy_initialized()) {
            $this->privacy_keys = [];
            foreach ($this->privacy as $privacy) {
                $this->privacy_keys[] = $privacy->privacy_key;
            }
        }
    }

    /**
     * @param $key
     * @return bool
     */
    public function isPrivate($key) {
        $this->initialize_privacy();
        return (in_array($key,$this->privacy_keys));
    }

So: Whenever i access the isPrivate($key) method, i cache the result for the next use so i don't hit the server too hard - the function may be accessed once or more - i just query once, the first time. I believe for my needs, this is the best way to do it.

I think a simple count > 0 check should suffice. This requires you to have defined the relationship with the hasMany method for the User Model.

if (count($user->privacy) > 0) {
   ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM