英文:
How to declare property in model which is calculated in request?
问题
以下是您提供的内容的翻译:
在laravel laravel/framework 9.52.5/ nunomaduro/larastan 2.6.0应用程序中使用以下命令运行检查:
./vendor/bin/phpstan analyse
我收到了错误行:
访问未定义的属性 App\Models\BannerCategory::$banner_clicked_counts_count。
指向请求的部分:
$bannerCategories = BannerCategory
::leftJoin((new Banner)->getTable(), (new Banner)->getTable().'.banner_category_id', '=', (new BannerCategory)->getTable() . '.id')
->orderBy('name', 'asc')
->addSelect(['banner_clicked_counts_count' => BannerClickedCount
::selectRaw('count(*)')
->whereColumn('banners.banner_category_id', 'banner_categories.id')
->whereColumn('banner_clicked_counts.banner_id', 'banners.id')
->whereRaw("banners.active = true ")
->getByCreatedAt($dateStart->startOfDay(), '>=')
->getByCreatedAt($dateEnd->endOfDay(), '<=')
->getByPageContentId($pageContentId)
->getByLocale($locale)
])
->get();
$seriesData = [];
foreach( $bannerCategories as $bannerCategory ) {
$seriesData[] = $bannerCategory->banner_clicked_counts_count; // 此行出错
$labelsData[] = $bannerCategory->name;
}
我修改了模型 app/Models/BannerCategory.php 如下:
class BannerCategory extends Model
{
use HasLocks;
use Sluggable;
use HasFactory;
protected $table = 'banner_categories';
protected $primaryKey = 'id';
public $timestamps = false;
protected $bannerClickedCountsCount = 0;
protected $appends = ['bannerClickedCountsCount'];
function getBannerClickedCountsCount(): int
{
\Log::info(varDump($this->bannerClickedCountsCount, ' -1 getBannerClickedCountsCount $this->bannerClickedCountsCount::'));
return $this->bannerClickedCountsCount;
}
function setBannerClickedCountsCount(int $bannerClickedCountsCount)
{
\Log::info(varDump($bannerClickedCountsCount, ' -1 setBannerClickedCountsCount $bannerClickedCountsCount::'));
return $this->bannerClickedCountsCount = $bannerClickedCountsCount;
}
}
跟踪SQL语句:
SELECT `banner_categories`.*, (SELECT count(*)
FROM `banner_clicked_counts`
WHERE `banners`.`banner_category_id` = `banner_categories`.`id` AND `banner_clicked_counts`.`banner_id` = `banners`.`id` AND banners.active = true AND banner_clicked_counts.created_at >= '2023-04-07 00:00:00' AND banner_clicked_counts.created_at <= '2023-05-07 23:59:59') AS `bannerClickedCountsCount`
FROM `banner_categories`
LEFT JOIN `banners` on `banners`.`banner_category_id` = `banner_categories`.`id`
ORDER BY `name` asc
我看到列bannerClickedCountsCount
的值大于0,但是function getBannerClickedCountsCount(): int
对于所有行都返回0(我记录了这个值)。我认为我以错误的方式设置了$bannerClickedCountsCount
的值。哪种方法是有效的?
我想正确设置它,而不是使用larastan忽略行。
英文:
Running checks in laravel laravel/framework 9.52.5/ nunomaduro/larastan 2.6.0 app with command
./vendor/bin/phpstan analyse
I got error line :
Access to an undefined property
App\Models\BannerCategory::$banner_clicked_counts_count.
Pointing at request :
$bannerCategories = BannerCategory
::leftJoin((new Banner)->getTable(), (new Banner)->getTable().'.banner_category_id', '=', (new BannerCategory)->getTable() . '.id')
->orderBy('name', 'asc')
->addSelect(['banner_clicked_counts_count' => BannerClickedCount
::selectRaw('count(*)')
->whereColumn('banners.banner_category_id', 'banner_categories.id')
->whereColumn('banner_clicked_counts.banner_id', 'banners.id')
->whereRaw("banners.active = true ")
->getByCreatedAt($dateStart->startOfDay(), '>=')
->getByCreatedAt($dateEnd->endOfDay(), '<=')
->getByPageContentId($pageContentId)
->getByLocale($locale)
])
->get();
$seriesData = [];
foreach( $bannerCategories as $bannerCategory ) {
$seriesData[] = $bannerCategory->banner_clicked_counts_count; // Error pointing at this line
$labelsData[] = $bannerCategory->name;
}
I modified model app/Models/BannerCategory.php as :
class BannerCategory extends Model
{
use HasLocks;
use Sluggable;
use HasFactory;
protected $table = 'banner_categories';
protected $primaryKey = 'id';
public $timestamps = false;
protected $bannerClickedCountsCount = 0;
protected $appends = ['bannerClickedCountsCount'];
...
function getBannerClickedCountsCount(): int
{
\Log::info(varDump($this->bannerClickedCountsCount, ' -1 getBannerClickedCountsCount $this->bannerClickedCountsCount::'));
return $this->bannerClickedCountsCount;
}
function setBannerClickedCountsCount(int $bannerClickedCountsCount)
{
\Log::info(varDump($bannerClickedCountsCount, ' -1 setBannerClickedCountsCount $bannerClickedCountsCount::'));
return $this->bannerClickedCountsCount = $bannerClickedCountsCount;
}
Tracing sql-statement :
SELECT `banner_categories`.*, ( SELECT count(*)
FROM `banner_clicked_counts`
WHERE `banners`.`banner_category_id` = `banner_categories`.`id` AND `banner_clicked_counts`.`banner_id` = `banners`.`id` AND banners.active = true AND banner_clicked_counts.created_at >= '2023-04-07 00:00:00' AND banner_clicked_counts.created_at <= '2023-05-07 23:59:59') AS `bannerClickedCountsCount`
FROM `banner_categories`
LEFT JOIN `banners` on `banners`.`banner_category_id` = `banner_categories`.`id`
ORDER BY `name` asc
I see that column bannerClickedCountsCount has value > 0, but method
function getBannerClickedCountsCount(): int
returns 0 for all rows(I log this value) .
I suppose I set $bannerClickedCountsCount value in wrong way. Which way is valid ?
I would like to set it correctly, not use larastan ignore line.
答案1
得分: 1
Sure, here's the translation of the provided code snippet:
你可以使用 $model->getAttribute('attribute');
你以 BannerCategory::leftJoin 开始查询,应该检索到 BannerCategory 的实例,即使实际上它不完全包含这些内容。
$bannerCategories = BannerCategory
::leftJoin((new Banner)->getTable(), (new Banner)->getTable().'.banner_category_id', '=', (new BannerCategory)->getTable() . '.id')
->orderBy('name', 'asc')
->addSelect(['banner_clicked_counts_count' => BannerClickedCount
::selectRaw('count(*)')
->whereColumn('banners.banner_category_id', 'banner_categories.id')
->whereColumn('banner_clicked_counts.banner_id', 'banners.id')
->whereRaw("banners.active = true ")
->getByCreatedAt($dateStart->startOfDay(), '>=') // getByCreatedAt 方法的调用
->getByCreatedAt($dateEnd->endOfDay(), '<=') // getByCreatedAt 方法的调用
->getByPageContentId($pageContentId) // getByPageContentId 方法的调用
->getByLocale($locale) // getByLocale 方法的调用
])
->get();
$seriesData = [];
foreach ($bannerCategories as $bannerCategory) {
$seriesData[] = $bannerCategory->getAttribute('banner_clicked_counts_count');
$labelsData[] = $bannerCategory->name;
}
Please note that I've included translations for the method calls as comments within the code.
英文:
You can use $model->getAttribute('attribute');
You started the query as BannerCategory::leftJoin that should retrieve an instance of BannerCategory, even if that is not exactly what it contains.
$bannerCategories = BannerCategory
::leftJoin((new Banner)->getTable(), (new Banner)->getTable().'.banner_category_id', '=', (new BannerCategory)->getTable() . '.id')
->orderBy('name', 'asc')
->addSelect(['banner_clicked_counts_count' => BannerClickedCount
::selectRaw('count(*)')
->whereColumn('banners.banner_category_id', 'banner_categories.id')
->whereColumn('banner_clicked_counts.banner_id', 'banners.id')
->whereRaw("banners.active = true ")
->getByCreatedAt($dateStart->startOfDay(), '>=')
->getByCreatedAt($dateEnd->endOfDay(), '<=')
->getByPageContentId($pageContentId)
->getByLocale($locale)
])
->get();
$seriesData = [];
foreach( $bannerCategories as $bannerCategory ) {
$seriesData[] = $bannerCategory->getAttribute('banner_clicked_counts_count');
$labelsData[] = $bannerCategory->name;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论