z-song / laravel-admin

Build a full-featured administrative interface in ten minutes
https://laravel-admin.org
MIT License
11.16k stars 2.82k forks source link

leftJoin 错误 #167

Closed edwinhuish closed 7 years ago

edwinhuish commented 7 years ago

如下图,按照Eloquent的leftJion方法出现以下问题,错误将表名当为方法名,并找不到方法后抛出错误。

image image

暂时如此改动后能够达到效果,烦请修复。 image image

z-song commented 7 years ago

你用leftJoin()联表,然后就直接用product_colors关系来获取联表数据?

edwinhuish commented 7 years ago

@z-song 抱歉,不懂,请指教。一般来说,不是直接下面这样就可以获取数据了么?

            $result = Product::leftJoin('product_color', function($join) {
                $join->on('products.id', '=', 'product_color.product_id');
            })->find(1);
            var_dump($result);

下面这里是我的gird() 代码:

protected function grid()
{

        return Admin::grid(Product::class, function (Grid $grid) {

            $grid->model()->leftJoin('product_color', 'products.id', '=', 'product_color.product_id');

            $grid->rows(function($row){
                $row->column('reference', function ($reference)  use ($row) {
                    return '<a href="/admin/products/' . $row->id . '">' . $reference . '</a>';
                });
            });
            $grid->column('pic_directory',trans('sql.picture'))->image('',100,100)->sortable();
            $grid->column('reference',trans('sql.reference'))->sortable();
            $grid->column('esp_name',trans('sql.esp_name'))->sortable();
            $grid->column('esp_color',trans('sql.esp_color'))->sortable();
            $grid->column('barcode',trans('sql.barcode'))->sortable();

            $grid->filter(function ($filter) {
                $filter->useModal();
                $filter->disableIdFilter();
                $filter->like('reference', trans('sql.reference'));
                $filter->like('esp_name', trans('sql.esp_name'));
            });
        });
    }

Product Model的代码。

class Product extends Model
{
    public function colors()
    {
        return $this->hasMany(ProductColor::class);
    }

    public function product_color()
    {
        return 'product_color';
    }
}
edwinhuish commented 7 years ago

写成下面这样可以运行,可是刚刚发现,为什么ID都是错的?

protected function grid()
    {
        return Admin::grid(Product::class, function (Grid $grid) {
            $grid->model()->leftJoin('product_color', function($join) {
                $join->on('products.id', '=', 'product_color.product_id');
            });

            $grid->rows(function($row){
                $row->column('reference', function ($reference)  use ($row) {
                    return '<a href="/admin/products/' . $row->id . '">' . $reference . '</a>';
                });
            });
            $grid->column('pic_directory',trans('sql.picture'))->image('',100,100)->sortable();
            $grid->column('reference',trans('sql.reference'))->sortable();
            $grid->column('esp_name',trans('sql.esp_name'))->sortable();
            $grid->column('esp_color',trans('sql.esp_color'))->sortable();
            $grid->column('barcode',trans('sql.barcode'))->sortable();

            $grid->filter(function ($filter) {
                $filter->useModal();
                $filter->disableIdFilter();
                $filter->like('reference', trans('sql.reference'));
                $filter->like('esp_name', trans('sql.esp_name'));
            });
        });
    }
class Product extends Model
{
    public function colors()
    {
        return $this->hasMany(ProductColor::class);
    }

    public function product_color()
    {
        return 'product_color';
    }
}
edwinhuish commented 7 years ago

得到的数据。 image

如果是直接用这条SQL 查数据库的话,得到的数据。 image

z-song commented 7 years ago

两张表的数据要显示在一个grid的里面,要不用关系,要不用join连表,不要两个一起用,它们不是一个概念。

$products = Product::leftJoin('product_color', 'products.id', '=', 'product_color.product_id')->find(1)->toArray();

var_dump($products);

看下输出数组的结构,照着结构来用$grid->column($keyName)的方式指定列,它会从上面输出的结构来构建grid。

id错误是因为两张表都有id字段,相同的字段,后表的会覆盖前表,你可以用字段别名的方式来规避这个问题。

z-song commented 7 years ago

还有一个问题,如果不用关系来连接第二张表的数据,那么第二张表的数据无法使用editable、sortable等一些需要通过关系查找的方法。

edwinhuish commented 7 years ago

@z-song 谢谢你的解答。我仅是业余兴趣学的编程,原生会指定需要获取的字段,以及设置字段别名,可是Eloquent不会使用。烦请指教!

另外,如何用关系来连接第二张表,并且做到left join的显示效果呢?

还有,我发现有$form里有一个hasMany($relationName, $callback) 请问这个怎么用?查遍了你得md文件,没有关于这个方法的说明。

z-song commented 7 years ago

据我所知关系和join操作貌似不能一起使用

grid支持 一对一 和 一对多,目前form只支持一对一,hasMany是用来实现表单中的一对多,但是能力有限实现起来有些困难,所以属于未完成的feature

edwinhuish commented 7 years ago

@z-song 关于form的hasMany,其实可以做个类似grid的表格,每一行都是一个子form,或者做成tab形式,每一个tab都是一个子form。

表格类子form比较直观,可以多行为一个form,然后用分隔符分割另外一个form。

tab类的子form相对比较容易实现布局,不太直观。

z-song commented 7 years ago

实现过一次 效果不太理想,就搁置了

内嵌一对多的form,实现起来有点复杂

edwinhuish commented 7 years ago

@z-song 不是内嵌,而是另外一个box:主表一个box,子表另外一个box。

无论哪个位置添加的子表,都应该按照顺序在下面以独立的BOX展示出来。

edwinhuish commented 7 years ago

@z-song 也可以看作子表的grid上面有主表的form而已。一样可以点击主表的编辑页面下面的子表gird进入子表的form。无非就是需要做好跳转。

这部分最好是用tab页来做,能避免很多跳转form数据丢失的问题。

另外一个解决方案就是,将所有编辑页面做成浮动的iframe, 可以参考 http://layer.layui.com/ 这种方式对于你现有的代码修改会很快。

edwinhuish commented 7 years ago

@z-song 请问有考虑添加此类功能的打算么?自己想要实现,可是无奈能力有限。。

edwinhuish commented 7 years ago

@z-song 如果做成下面这种形式呢?

2

z-song commented 7 years ago

@edwinhuish 这个效果很赞!

edwinhuish commented 7 years ago

@z-song 求扩展。。。我自己乱写的,不通用。。。求大神扩展这个功能。

edwinhuish commented 7 years ago

@z-song 貌似 Form 能够扩展,Gird不支持扩展。需要修改源代码。断点调试过几次,一直没有看到怎么通过$gird->attr($name, $label) 这种形式,既支持字段名,也支持eloquent的一对多。

amun1303 commented 7 years ago

@edwinhuish : Could you share your code, how to implement that action by using laravel admin. Thank you so much. https://cloud.githubusercontent.com/assets/5207925/20894642/39a376c6-bb51-11e6-942c-ad43d9166928.gif

technilogics commented 1 year ago

@edwinhuish as @amun1303 requested, it will be good if you share or at least explain how you show color count in load model popup for colors list.