Php 如何在Laravel中创建hasManyThrough关系?
我正在尝试为我的表创建一个in-Laravel 这是我的表格结构的一个高级部分 我有调查问卷。(一个问题属于多个控件Php 如何在Laravel中创建hasManyThrough关系?,php,mysql,laravel,orm,laravel-5,Php,Mysql,Laravel,Orm,Laravel 5,我正在尝试为我的表创建一个in-Laravel 这是我的表格结构的一个高级部分 我有调查问卷。(一个问题属于多个控件survey\u questions.id=survey\u question\u controls.question\u id) 我有调查问题控制表(许多控制属于一个问题,即survey\u question\u controls.question\u id=survey\u questions.id) 我还有调查控制项(许多项属于一个控制项,即调查控制项.control\u i
survey\u questions.id=survey\u question\u controls.question\u id
)
我有调查问题控制表(许多控制属于一个问题,即survey\u question\u controls.question\u id=survey\u questions.id
)
我还有调查控制项(许多项属于一个控制项,即调查控制项.control\u id=调查问题控制项.id
)
我需要为问题与项目建立一个hasManyThrough
关系
以下是我的表格定义
CREATE TABLE `survey_questions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(120) COLLATE utf8_unicode_ci NOT NULL,
`survey_id` int(10) unsigned NOT NULL,
`sort` mediumint(9) NOT NULL DEFAULT '0',
`page_number` smallint(5) unsigned NOT NULL,
`is_required` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`visible_level` enum('All','store','region','district','division') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'All',
`visible_to` varchar(120) COLLATE utf8_unicode_ci NOT NULL,
`visible` enum('Always','conditional') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Always',
`status` enum('active','inactive') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'active',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `survey_questions_survey_id_index` (`survey_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `survey_question_controls` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`question_id` int(10) unsigned NOT NULL,
`input_type` enum('text','textarea','radio','checkbox','menu','list') COLLATE utf8_unicode_ci NOT NULL,
`sort` mediumint(9) NOT NULL DEFAULT '0',
`validation_rule` enum('none','number','text') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'none',
`min_length` int(10) unsigned DEFAULT NULL,
`max_length` int(10) unsigned DEFAULT NULL,
`min_value` int(11) DEFAULT NULL,
`max_value` int(11) DEFAULT NULL,
`refuse` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`disqualify` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`status` enum('active','inactive') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'active',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `survey_question_controls_question_id_index` (`question_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `survey_control_items` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(120) COLLATE utf8_unicode_ci NOT NULL,
`control_id` int(10) unsigned NOT NULL,
`sort` mediumint(9) NOT NULL DEFAULT '0',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `survey_control_items_control_id_index` (`control_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
我试图用拉威尔的ORM得到与这个问题类似的数据
SELECT * FROM survey_questions AS q
INNER JOIN survey_question_controls AS c ON c.question_id = q.id
LEFT JOIN survey_control_items AS i ON i.control_id = c.id
在我的调查问题模型中,我添加了这种关系
/**
* Get items for the controls that belongs to the question
* Questions > controls >
*/
public function items()
{
return $this->hasManyThrough(Surveyquestioncontrols::class, Surveycontrolitems::class, 'question_id', 'id', 'control_id', 'control_id');
}
这给了我以下SQL错误
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'survey_control_items.surveyquestioncontrols_id' in 'where clause' (SQL: select * from `survey_control_items` where `survey_control_items`.`surveyquestioncontrols_id` = 1 and `survey_control_items`.`surveyquestioncontrols_id` is not null)
问题
如何创建hasManyThrough关系
已编辑
阅读上述错误时,您会注意到a列名称不存在survey\u control\u items.surveyquestioncontrols\u id
此列应为survey\u control\u items.control\u id
另外,根据下面的反馈,my items()方法应该如下所示
/**
* Get items for the controls that belongs to the question
* Questions > controls >
*/
public function items()
{
return $this->hasManyThrough(Surveycontrolitems::class, Surveyquestioncontrols::class, 'question_id', 'control_id');
}
此错误可能是因为您错误地使用了
hasManyThrough()
方法
如果您的模型类位于命名空间“App”中,请尝试:
return $this->hasManyThrough('App\Surveycontrolitems', 'App\Surveyquestioncontrols', 'question_id', 'control_id');
来源:并且您对模型使用了错误的参数顺序 传递给hasManyThrough方法的第一个参数是我们希望访问的最终模型的名称,而第二个参数是中间模型的名称 外键呢 第三个参数是中间模型上外键的名称,而第四个参数是最终模型上外键的名称
公共功能项()
{
返回$this->hasManyThrough(
测量控件::类,
Surveyquestioncontrols::类,
“问题编号”,
“控制id”
);
}
如果您对模型和数据库表使用适当的驼峰和蛇形外壳,并根据实际相关的表名命名外键,那么所有这些都将是自动完成的。我意识到我写的是错误的,这就是我删除它的原因。抱歉,还是同样的问题。如果您查看我在问题中列出的错误,您会注意到生成的WHERE子句具有以下列
survey\u control\u items
surveyquestioncontrols\u id
,该列无效。它应该是survey\u control\u items
control\u id
我知道Laravel假设surveyquestioncontrols\u id
应该存在,但在我的情况下,我想用“id”来代替它,即survey\u control\u items
id仍然存在同样的问题。请看我对凯文回答的回复。必须有第五个和第六个参数才能容纳自定义表名称中间键应该是“id”,最后一个键应该是“control_id”,所以我做了这个return$this->hasManyThrough(Surveycontrolitems::class,Surveyquestioncontrols::class,'id',control_id')
但是错误消息仍然假设IDSS已经有两个人告诉过你如何使用hasManyThrough方法,但是你坚持忽略我们的建议。请阅读文档。您将看到该方法中的第三个参数不应该是id
,而应该是question\u id
。这是因为它是中间模型的外键。在您的案例中,这是Surveyquestioncontrols
Surveyquestioncontrols
必须引用回父模型,它表示survey_questions
表。@KevinLee不是我坚持要正确,而是我试图解决一个即使在您推荐后仍然存在的问题。无论如何,items()现在返回以下$this->hasManyThrough(Surveycontrolitems::class,Surveyquestioncontrols::class,'question_id','control_id')代码>但仍然存在相同的错误未找到列:“where子句”中的1054未知列“survey\u control\u items.surveyquestioncontrols\u id”(SQL:从
survey\u control\u items`中选择*其中survey\u control\u items
surveyquestioncontrols\u id
=1和survey\u control\u items
surveyquestioncontrols\u id
不为空)`@MikeA,很抱歉,我只是试着完全按照文档中的方法来做,效果非常好。如果你看hasManyThrough的源代码,没有第六个参数,而且没有第六个参数是毫无意义的。本地_id有一个fith参数,这在你的情况下是不需要的(仅当“调查问题”中的“id”的名称不同时。请参阅我关于正确命名外键的建议。