You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Laravel 5.6的多对多关联表Select2搜索栏实现咨询

嘿,我来帮你搞定这个Laravel 5.6的多对多关联+Select2搜索问题!先看看现有代码里的小问题,再一步步调整到符合需求~

Laravel 5.6 多对多关联+Select2搜索实现方案

你当前的项目有COIN(字段id、name)和EVENT(字段id、title、description)两张表,通过中间表coin_event实现多对多关联,需要实现一个带Select2的多选搜索栏,选中币种后返回其关联的所有状态为APROBADO的事件,下面是具体调整方案:

1. 修正模型与迁移的细节

Coin模型

关联方法可以明确指定中间表并开启时间戳维护(可选,但更规范):

// app/Coin.php
public function events() {
    return $this->belongsToMany(Event::class, 'coin_event')
                ->withTimestamps(); // 自动维护中间表的created_at/updated_at
}

Event模型

同理优化关联方法:

// app/Event.php
public function coins() {
    return $this->belongsToMany(Coin::class, 'coin_event')
                ->withTimestamps();
}

中间表迁移

添加外键约束,保证数据关联的严谨性:

// database/migrations/xxxx_xx_xx_create_coin_event_table.php
public function up() {
    Schema::create('coin_event', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('coin_id');
        $table->unsignedInteger('event_id');
        $table->timestamps();

        // 新增外键约束,删除主表记录时自动删除中间表关联数据
        $table->foreign('coin_id')->references('id')->on('coins')->onDelete('cascade');
        $table->foreign('event_id')->references('id')->on('events')->onDelete('cascade');
    });
}

2. 重构PageController的search方法

你原来的方法存在逻辑错误:findMany返回的是集合,无法链式调用查询构造器的orderBy和where。我们直接从Event模型出发,通过关联筛选更高效:

// app/Http/Controllers/PageController.php
use Illuminate\Http\Request;
use App\Coin;
use App\Event;

public function search(Request $request) {
    // 验证请求参数,确保选中的币种ID存在于coins表
    $request->validate([
        'coinSearch' => 'required|array|exists:coins,id'
    ]);

    // 筛选关联选中币种、状态为APROBADO的事件,按event_at倒序分页
    $events = Event::whereHas('coins', function($query) use ($request) {
                    $query->whereIn('coins.id', $request->coinSearch);
                })
                ->where('status', 'APROBADO')
                ->orderBy('event_at', 'DESC')
                ->paginate(8);

    // 获取所有币种用于Select2下拉框
    $coins = Coin::all();

    return view('welcome', compact('events', 'coins'));
}

3. 完善Welcome视图(添加Select2初始化)

你的视图已经有了Select2的HTML结构,但缺少JS初始化,同时修正一些动态数据的硬编码问题:

<form name="form" method="get" class="form" role="form" action="{{ route('search') }}">
    {{ csrf_field() }}
    <div class="form-group">
        <select class="select2 select-coin col-12 form-control" id="coinSearch" name="coinSearch[]" multiple="multiple" style="width: 260px;" required>
            @foreach ($coins as $coin)
                <!-- 提交后保留选中状态,注意字段名和数据库一致,若你的字段是coin_name则改回 -->
                <option value="{{ $coin->id }}" {{ in_array($coin->id, old('coinSearch', [])) ? 'selected' : '' }}>
                    {{ $coin->name }}
                </option>
            @endforeach
        </select>
        <button class="btn btn-rounded btn-info">Buscar</button>
    </div>
</form>

<div class="row">
    @foreach ($events as $event )
        <div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
            <div class="card text-center">
                <div class="card-header">
                    <h5>
                        <strong>{{ \Carbon\Carbon::parse($event->event_at)->toFormattedDateString() }}</strong>
                        <!-- 修正模态框动态数据,替换硬编码内容 -->
                        <a class="reminder" href="#alertReminder" data-toggle="modal" data-target="#alertReminder" 
                           data-idevent="{{ $event->id }}" 
                           data-date="{{ \Carbon\Carbon::parse($event->event_at)->toFormattedDateString() }}" 
                           data-coin="{{ $event->coins->pluck('name')->implode(', ') }}" 
                           data-title="{{ $event->title }}">
                            <i class="far fa-clock"></i>
                        </a>
                    </h5>
                    @foreach ($event->coins as $coin)
                        <h5 style="display: inline;">
                            <strong><span>{{ $coin->name }} ({{ $coin->coin_symbol }})</span></strong>
                        </h5>
                    @endforeach
                    <h6>{{ $event->title }}</h6>
                </div>
                <div class="card-body">
                    <h5 class="card-title">
                        <small>(Publicado: {{ \Carbon\Carbon::parse($event->created_at)->toFormattedDateString() }})</small>
                    </h5>
                    <p class="card-text">{{ $event->description }}</p>
                    <a class="btn btn-xs btn-outline-primary waves-effect waves-light proof_modal" href="{{ asset($event->proof) }}">
                        <span class="btn-label"><i class="fa fa-file-photo-o"></i></span> Prueba
                    </a>
                    <a class="btn btn-xs btn-outline-primary waves-effect waves-light" target="_blank" href="{{ $event->source }}">
                        <span class="btn-label"><i class="fa fa-external-link-square"></i></span> Fuente
                    </a>
                </div>
                <div class="card-footer">
                    <h6 class="text-footer-card"><small>Publicado por: {{ $event->twitter_account }}</small></h6>
                    @if(empty($event->wallet_address))
                        <h6 class="text-footer-card"><small>ETH: 0x6e4Cf4b17086cD4Aae40Dbe9cB998d8460F0FbC6</small></h6>
                    @else
                        <h6 class="text-footer-card"><small>{{ $event->wallet_type }}: {{ $event->wallet_address }}</small></h6>
                    @endif
                </div>
            </div>
            <br>
        </div>
    @endforeach
</div>

<div class="text-center">
    {{ $events->links() }}
</div>

<!-- 引入Select2的CSS和JS -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>

<script>
$(document).ready(function() {
    // 初始化Select2,添加占位提示
    $('#coinSearch').select2({
        placeholder: "Selecciona una o varias monedas",
        allowClear: true
    });
});
</script>

4. 路由配置

别忘了在routes/web.php中添加对应路由:

Route::get('/search', 'PageController@search')->name('search');

这样整个流程就通顺了:用户通过Select2多选币种,提交表单后控制器查询关联这些币种且状态为APROBADO的事件,分页返回给视图展示。


内容的提问来源于stack exchange,提问作者Felipe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:12:05