【问题标题】:Users address logic in laravel用户在 laravel 中寻址逻辑
【发布时间】:2017-12-13 07:43:20
【问题描述】:

我在我的 laravel 应用程序 usersaddresses 中有 2 个表,它们都在工作,我想做的是:

  1. 为每个用户设置多个地址(完成)
  2. 设置主要地址(在订单设置和个人资料页面中选择的能力)

问题是:

我是否需要第三张表(例如 address_user)来获取用户和地址 ID,或者现在我只需将 primary 列添加到地址表中即可?

这是我所拥有的:

user型号

public function addresses(){
       return $this->hasMany(Address::class);
    }

Address型号

public function user(){
     return $this->belongsTo(User::class);
  }

Address table

Schema::create('addresses', function (Blueprint $table) {
            $table->increments('id');
            $table->string('address');
            $table->string('city');
            $table->string('postalcode')->nullable();
            $table->string('province');
            $table->integer('user_id')->unsigned();
            $table->timestamps();
        });
        Schema::table('addresses', function (Blueprint $table) {
            $table->foreign('user_id')->references('id')->on('users');
        });

这就是我当前在用户索引中打印数据的方式

<td class="text-center">
  <ol>
    @foreach($user->addresses as $uad)
       <li>{{$uad->address}}<br>{{$uad->city}},{{$uad->postalcode}},{{$uad->province}}</li>
    @endforeach
  </ol>
</td>

更新

因此,根据建议,我将列 is_primary 添加到我的 addresses 表中,我可以设置为 01 以获取用户的主要地址,但是

现在我在我的用户编辑页面中,我有 2 个地址属于用户 id 1 现在我想将选定的主地址更改为另一个 地址,但我在用户个人资料中编辑我如何更新我的地址表 is_primary 列,而我的表单路径是 users.update 而不是 addresses_update

更新 2

我做了一些改动,这里是:

  1. Users 表有address_id
  2. 地址表不再有is_primary 列。 为什么?因为用户可以将许多地址设置为主要地址!通过这种方式,用户只能将 1 个地址设置为主地址,这将获得该地址的 id。

问题

1- 我无法获取用户主地址(不知道如何!)

这是我获取用户地址的方法:

@foreach($user->addresses as $address)
  <p>
    {{$address->address}}<br>
    {{$address->city}}, {{$address->province}}<br>
    {{$address->country}}<br>
    {{$address->postalcode}}
  </p>
@endforeach

但我无法获取用户主地址。

【问题讨论】:

  • 您仍然可以保留您的地址,只需添加名为public function primaryAddress() { return $this-&gt;address-&gt;where('is_primary',1) } 的新方法
  • @user2749200 我更新了我的问题,请看一下。
  • 您传递所选地址的 id 并在您的控制器中设置 is_primary 1 的值。并保存应类似于 $user->address()->save($address) 的地址;` 仅供参考,您可能还需要将第一个主地址 is_primary 更新为 0

标签: php laravel


【解决方案1】:

因为$user-&gt;addresses 将为您提供Illuminate\Database\Eloquent\Collection 的实例,所以您可以根据需要过滤该集合。

User类方法示例:

public function getPrimaryAddress(): Address
{
    return $this->addresses->where("is_primary", "=", 1)->first();
}

当然,您首先要获得所有地址,在大多数情况下,无论如何您都会这样做。 如果您想发出单个查询并获取主地址,您仍然可以这样做

public function getPrimaryAddress(): Address
{
    return Address::where('user_id', '=', $this->id)->andWhere('is_primary', '=', 1)->first();
}

但这两者都暗示您在addresses 表中有is_primary 列。

如果您想获取一个列表并在循环中检查该地址是否是主要地址,那么在您的 addresses 表中包含 is_primary 将是有益的,例如

foreach ($user->addresses as $address) {
    if ($address->is_primary) { /* this address is primary */ }
}

要更改主地址,您需要将已经是主地址的is_primary 设置为0,并将现在主地址的属性is_primary 设置为1

public function setPrimaryAddress($address): bool
{
    if (is_numeric($address)) { // Should be PK.
        $address = Address::find($address);
    }
    $prev = $this->getPrimaryAddress();
    if ($address->id == $prev->id) {
        return true;
    }
    if ($prev->update(['is_primary' => 0])) {
        return $address->update(['is_primary' => 1]);
    }
    return false;
}

【讨论】:

  • 谢谢,这里还有 1 个问题:当我在用户控制器中使用 getPrimaryAddress 时,我应该在订单表中使用什么来获取这个特定地址而不是其他地址?或者在我的用户个人资料中向他/她显示这个是主要地址而其他地址不是? (对不起,只是想对我说清楚)
  • 不客气。如果我正确理解了问题,则回答了答案中的问题:)
  • 谢谢你,我测试它是否有效,如果没有我会接受你的答案,我会再问一次:)
  • 嘿伙计,我有一个问题?现在我在我的用户编辑页面中,我有 2 个地址属于 ID 为 1 的用户现在我想将选定的主地址更改为其他地址,但我在用户个人资料编辑中如何更新我的地址表 user_id 而我的表单路线是users.update 而不是addresses_update
  • 更新了答案^
【解决方案2】:

如果您想拥有它,以便一个用户可以拥有多个地址,而且一个地址可以属于多个用户,那么使用像 address_user 建议的数据透视表的多对多关系可以正常工作。如果您想避免重复数据或者您想考虑几个人共享一个地址,这将非常有用。

关于允许用户拥有主地址,您的想法是正确的。只需在您的用户表中添加一列,该列指向地址表中的主要地址,应该就是这样。如果您采用多对多方法,您可以在数据透视表中添加另一个字段以将地址标记为用户的主要地址。

回复:更新 2。

通过您所做的更改,获取用户的主要地址应该很容易。你有几个选择。如果您正在遍历用户的地址,您可以简单地将$user-&gt;primary_address_id(或在您的情况下为address_id)字段与$address-&gt;id 进行比较:

@foreach ($user->addresses as $address)
  @if ($address->id == $user->primary_address_id)
    <p>Do something with your primary address</p>
  @endif
  <p>
    {{ $address->address }}<br>
    {{ $address->city }}, {{ $address->province }}<br>
    {{ $address->country }}<br>
    {{ $address->postalcode }}
  </p>
@endforeach

我建议向您的 User 模型添加一个方法来帮助您解决这个问题。像这样的东西可以解决问题:

class User extends Model
{
    // ..

    public function isPrimaryAddress(Address $address)
    {
        return $this->primary_address_id == $address->id;
    }
}

这样您就可以将上述模板代码中的if ($address-&gt;id == $user-&gt;primary_address_id) 替换为@if ($user-&gt;isPrimaryAddress($address))。这有助于使您的代码更具可读性。

现在,如果您愿意,您还可以向您的用户模型添加另一个关系来获取您用户的主要地址:

class User extends Model
{
    // ..

    public function primaryAddress()
    {
        return $this->hasOne(Address::class, 'id', 'primary_address_id');
    }
}

那么,如果您想获取用户的主要地址,您只需要这样做:

$primaryAddress = $user->primary_address;

【讨论】:

  • answer to first: 不,我不想给我所有的用户任何公共地址,每个用户可以有或没有自己的地址。 To the second: 所以你建议我在我的用户表而不是地址表中添加列来获得主要权利?
  • 在这种情况下,您不需要数据透视表并且可以坚持一对多关系。就个人而言,是的,我会在users 表中添加一个primary_address_id。或者,您可以在addresses 表中添加一个primary 列,但这在技术上允许一个用户拥有多个主要地址,因此我可能会选择前者,具体取决于您的要求。
  • @mafortis 你好,我已经更新了我的回答来回答你的第二个问题
  • 嗨,兄弟,我尝试了用户模型方法,但它不起作用,但我设法以其他方式完成。这里是@foreach($user-&gt;addresses as $index =&gt; $address) {{$address-&gt;country}} @if($user-&gt;address_id == $address-&gt;id) primary @else not primary @endif
  • 嗨@mafortis。是的,我只是使用了primary_address_id,因为它更能描述它所代表的内容,特别是为了说明我在回答中的观点。这就是我写“$user-&gt;primary_address_id(或者在你的情况下为address_id)”的原因:)
【解决方案3】:

已解决

在将address_id 添加到我的用户表并获取地址 id 作为主地址之后,我就是如何获取所有用户的地址并将主地址与其他人分开。

@foreach($user->addresses as $index => $address)
<tr>
 <td class="text-center">{{$index+1}}</td>
 <td class="text-center">{{$address->address}}</td>
 <td class="text-center">{{$address->city}}</td>
 <td class="text-center">{{$address->province}}</td>
 <td class="text-center">{{$address->country}}</td>
 <td class="text-center">{{$address->postalcode}}</td>
 <td class="text-center">
 <div class="funkyradio">
  @if($user->address_id == $address->id)
 <div class="funkyradio-success">
  <input type="checkbox" name="checkbox" id="yes" checked/>
  <label for="yes">Yes</label>
 </div>
  @else
 <div class="funkyradio-default">
  <input type="checkbox" name="checkbox" id="no"/>
  <label for="no">NO</label>
 </div>
  @endif
@endforeach

感谢 JonathonNemoden 对他们的帮助(投票)。

【讨论】:

  • 嗨@mafortis,如果我们创建一个像address_user 这样的数据透视表会怎样。您对此有何看法?
  • @DurgeshPandey 嗨,在我的情况下,我的表名是地址,而在你的情况下,表名是 address_user,但我猜逻辑是一样的。 Ps:我强烈建议您对表使用复数名称,例如地址,否则您最终会在模型中静态设置表名,并且将来会出现更多错误
  • 感谢您在addresses_user 上纠正我。我会记住的。
猜你喜欢
  • 2017-12-18
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 2018-07-12
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
相关资源
最近更新 更多