itsmill3rtime / listify
将任何 Eloquent 模型转换为列表!http://lookitsatravis.github.io/listify
Requires
- php: >=5.5.0
- illuminate/console: >=5.0
- illuminate/database: >=5.0
- illuminate/events: >=5.0
- illuminate/support: >=5.0
Requires (Dev)
- phpunit/phpunit: >=4.0
- satooshi/php-coveralls: dev-master
- way/phpunit-wrappers: dev-master
README
将任何 Eloquent 模型转换为列表!
描述
Listify
提供了排序和重新排列列表中多个对象的功能。具有此指定的类需要在映射的数据库表上定义一个 position
列作为整数。Listify
是 Ruby gem acts_as_list
(https://github.com/swanandp/acts_as_list)的 Eloquent 版本。
要求
Listify
目前需要 php >= 5.5(Listify
通过 traits 实现)。- Laravel 5.0 或更高版本
若要使用 Laravel 4,请使用版本 1.0.6。
安装
Listify
以 composer 包的形式分发,这是在您的应用程序中使用它的方式。
使用 Composer 安装此包。编辑您项目中的 composer.json
文件,以要求 lookitsatravis/listify
。
"require": { "laravel/framework": "~5.0", "lookitsatravis/listify": "~1.2" }
完成此操作后,下一步是添加服务提供者。打开 app/config/app.php
,向 providers 数组中添加一个新项。
'Lookitsatravis\Listify\ListifyServiceProvider'
可选地,您可以定义 Listify
trait 的别名。打开 app/config/app.php
,向 aliases 数组中添加一个新项。
'Listify' => 'Lookitsatravis\Listify\Listify'
快速入门
首先,您需要添加一个列来存储位置。从命令行使用迁移生成器
php artisan listify:attach {table_name} {position_column_name} php artisan migrate
{table_name}
是必需的参数。{position_column_name}
是可选的,默认值为 "position"。
然后,在您的模型中
class User extends Eloquent { use \Lookitsatravis\Listify\Listify; public function __construct(array $attributes = array(), $exists = false) { parent::__construct($attributes, $exists); $this->initListify(); } }
确保在您的模型中调用
initListify()
方法后调用parent::__construct()
。
这就是获取 Listify
热度所需的所有内容。
概述
添加到 Eloquent 模型中的实例方法
您将为添加了 Listify
的每个 Eloquent 模型实例添加一些方法。
在 Listify
中,“更高”意味着列表中更靠前(更低的 position
),而“更低”意味着列表中更靠后(更高的 position
)。这可能有些令人困惑,因此添加一些测试来验证您是否根据上下文正确使用方法可能是有意义的。
更改位置和重新排序列表的方法
eloquentModel.insertAt(2)
eloquentModel.moveLower()
如果项目是最低项,将不会执行任何操作eloquentModel.moveHigher()
如果项目是最高项,将不会执行任何操作eloquentModel.moveToBottom()
eloquentModel.moveToTop()
eloquentModel.removeFromList()
不立即重新排序列表的更改位置的方法
注意:更改的位置将在模型保存时触发对列表中其他项目的更新
eloquentModel.incrementPosition()
eloquentModel.decrementPosition()
eloquentModel.setListPosition(3)
返回项目列表位置属性的方法
eloquentModel.isFirst()
eloquentModel.isLast()
eloquentModel.isInList()
eloquentModel.isNotInList()
eloquentModel.isDefaultPosition()
eloquentModel.higherItem()
eloquentModel.higherItems()
将返回列表中eloquentModel
上方的所有项目(按位置排序,升序)eloquentModel.lowerItem()
eloquentModel.lowerItems()
将返回列表中eloquentModel
下方的所有项目(按位置排序,升序)
##配置
有几个配置选项可用。您需要将这些作为数组参数传递到您的模型构造函数中的 initListify()
。以下是选项
top_of_list
设置列表顶部的整数位置(默认:1
)。column
设置您在安装过程中选择的定位列名称(默认:'position'
)。add_new_at
设置您在安装过程中选择的定位列名称(默认:'bottom'
,选项:'top'
或'bottom'
)。scope
允许您限定列表中的项目。这个选项需要一些详细说明。接受三个可能的值:字符串
Illuminate\Database\Eloquent\Relations\BelongsTo
对象Illuminate\Database\Query\Builder
对象
###字符串
如果传递了 string
,则将原始字符串作为 whereRaw
传递给作用域。这允许您执行类似 'custom_foreign_key = 42'
的操作,并将所有项目限定在该结果集中。您可以传递复杂的 where
子句,并且它将被直接传递到每个数据库操作中。
示例
class User extends Eloquent { use \Lookitsatravis\Listify\Listify; public function __construct(array $attributes = array(), $exists = false) { parent::__construct($attributes, $exists); $this->initListify([ 'scope' => 'answer_to_ltuae = 42' ]); } }
结果为以下作用域:
WHERE answer_to_ltuae = 42
###Illuminate\Database\Eloquent\Relations\BelongsTo
如果传递了 Illuminate\Database\Eloquent\Relations\BelongsTo
,则 Listify
将匹配作用域的外键与模型实例相应外键的值。
示例
class ToDoListItem extends Eloquent { use \Lookitsatravis\Listify\Listify; public function __construct(array $attributes = array(), $exists = false) { parent::__construct($attributes, $exists); $this->initListify([ 'scope' => $this->toDoList() ]); } public function toDoList() { $this->belongsTo('ToDoList'); } }
结果为以下作用域:
WHERE to_do_list_id = {{toDoListItem.to_do_list_id的值}}
###Illuminate\Database\Query\Builder
最后,如果传递了 Illuminate\Database\Query\Builder
,则 Listify
将提取构建器的 where
子句并将其用作 Listify
项的作用域。添加这种作用域类型是为了在 acts_as_list
版本和 Listify
之间保持一致性;然而,由于语言和 ActiveRecord 与 Eloquent 之间的差异,目前的实现有限,需要改进以更灵活和更安全。这是一个很大的限制,将在即将发布的版本中首先解决。
这个选项有点复杂,因为它需要在 PDO 之外准备查询对象的 where
数组并作为原始字符串传递。所以,请记住,如果对对象的结构不加以小心,这个途径可能会让您的应用程序容易受到滥用。如果您使用直接的用户输入,请在将其用作 Listify
的作用域之前对数据进行清理。
示例
class ToDoListItem extends Eloquent { use \Lookitsatravis\Listify\Listify; public function __construct(array $attributes = array(), $exists = false) { parent::__construct($attributes, $exists); $this->initListify([ 'scope' => DB::table($this->getTable())->where('type', '=', 'Not A List of My Favorite Porn Videos') ]); } }
结果为以下作用域:
to_do_list_items.type = 'Not A List of My Favorite Porn Videos'
更改配置
您也可以在运行时使用 $this->setListifyConfig('key', 'value');
修改任何配置值。例如,要更改作用域,可以这样做:
$this->setListifyConfig('scope', 'what_does_the_fox_say = "ring ding ding ding"');
当处理更新时,将使用原始作用域来从该列表中删除记录,并将其插入到新的作用域列表中。请注意。在处理过程中更改配置可能会产生不可预测的影响。
注意事项
在特质方法内部的所有 position
查询(选择、更新等)都在没有默认作用域的情况下执行,这可以防止当默认作用域与 Listify
作用域不同时的糟糕问题。
在调用验证之后设置 position
列,因此您不应该在 position
列上放置 presence
验证。
未来计划
- 支持使用闭包作为作用域
- 更新
Illuminate\Database\Query\Builder
作用域以提高安全性和灵活性 - 为安装命令添加更多功能。例如:
- 自动更新模型特质(包括构造函数中的 init 方法)
- 生成(或添加)一个控制器,其中包含为每个
Listify
公共方法执行的动作,包括添加必要的路由。这将使通过 AJAX-y 前端调用类似https://:8000/foos/1/move_lower
变得容易。
除此之外,我还希望根据需要与 Ruby gem acts_as_list
保持一致(https://github.com/swanandp/acts_as_list)。
为 Listify
贡献
- 查看最新主分支以确保该功能尚未实现或错误尚未修复
- 查看问题跟踪器,以确保没有人已经提出或贡献过这个问题
- 创建项目的分支
- 开始一个功能/错误修复分支
- 提交并推送,直到你对你的贡献满意为止
- 请确保为其添加测试。这是很重要的,这样我就不会无意中在未来的版本中破坏它。
- 请尽量不要修改Composer.json、版本或历史记录。如果你想要有自己的版本,或者这是必要的,那是可以的,但请将其隔离到自己的提交中,这样我就可以围绕它进行选择。
- 我建议在发送拉取请求之前,使用Laravel 5.0及以上版本来测试构建。
版权
版权所有(c)2013-2017 Travis Vignon,在MIT许可下发布