上下文
当用户(会议创建者)创建会议时,他可以为该会议创建注册表单。因此,他访问页面“http://proj.test/conference/edit/1/questions”以将表单编辑为ID为1的会议。
在此页面中,他可以通过复选框将现有问题与每种注册类型相关联。他还可以点击“添加自定义问题”,向表单添加更多自定义问题。
例如,他可以创建一个自定义问题“你的电话号码是什么?”并且可以将此问题与例如“通用”的注册类型或之前创建的任何其他所有注册类型相关联。
因此,当会议创建者访问“http://proj.test/conference/edit/1/questions/create”时,他可以访问表单,为ID为1的会议创建新的自定义问题。
在此表单中,用户(会议创建者)需要选择问题的标题(例如:电话号码)和问题类型(例如:文本),然后单击“存储问题”。
问题类型字段是一个包含5个选项的选择菜单(文本,长文本,单选按钮,选择菜单和复选框)。 如果用户选择问题类型作为单选按钮,则选择菜单或复选框会显示一些文本输入,以便用户可以插入每个选项的值。
然后在用户进行注册的前端,例如用户John在注册类型“Rt 001”中注册了2个参与者,他和Jake,所以他需要填写表格,在此例如,他需要填写每个参与者的字段,因为会议创建者选择了“从所有参与者收集信息”选项。注册表始终询问进行注册的用户的姓名和电子邮件,但在这种情况下,注册表还会询问用户“您的电话号码是什么”,因为会议创建者创建的此字段由会议关联用户正在注册的注册类型的创建者(Rt 001):
疑惑:
我对如何根据表,列和关系组织这个上下文以正确建模这些部分有一些疑问:
//会议模型
class Conference extends Model
{
// A conference has many registration types
public function registrationTypes(){
return $this->hasMany('App\RegistrationType', 'conference_id');
}
// A conference can have many questions
public function questions(){
return $this->hasMany('App\Question', 'conference');
}
// A conference has one organizer
public function organizer(){
return $this->belongsTo('App\User', 'user_id');
}
}
RegistrationType模型:
class RegistrationType extends Model
{
public function conference(){
return $this->belongsTo('App\Conference');
}
// A registration type has many questions
public function questions(){
return $this->hasMany('App\Question', 'registration_type_id');
}
}
//问题模型
class Question extends Model
{
public function conference(){
return $this->belongsTo('App\Conference');
}
public function registration_type(){
return $this->belongsTo('App\RegistrationType');
}
}
数据库图表,它不完整,可能不正确对此上下文进行建模,但显示了我现在拥有的图像图:http://ibb.co/gVYVJS
答案 0 :(得分:1)
根据我从问题和讨论中获得的信息,我进行了架构更改。注意:在此模式中,我使用laravel使用的命名标准(默认情况下)。像多个表名一样,主键将是' id'等
大部分内容与问题中的架构类似。我会解释一下,
上述架构为每种注册类型添加了required
选项,因此您可以在一种类型中强制提出问题,而在另一种类型中不强制使用。必填字段已添加为extra attribute到registration_type_questions
数据透视表。
根据注册类型查找问题
class RegistrationType extends Model
{
public function questions(){
return $this->belongsToMany(App\Question::class, 'registration_type_questions');
}
}
$registration_type->questions->withPivot('required');
由参与者添加问题答案。
class Answer extends Model
{
public function question(){
return $this->belongsTo(App\Question::class);
}
public function participant(){
return $this->belongsTo(App\Participant::class);
}
}
Answer::create([
'participant_id' => $participant_id,
'question_id' => $question_id,
'answer' => 'answer'
])
在conference_id
表
questions
conference_id
举行问题所属的会议。这对于在编辑/创建会议页面中显示已创建的问题非常有用。
如何处理用户注册
only_for_registration
标记仅适用于持有注册的用户'给出会议创建页面的选项。如果为false,则表示您不会向其他参与者显示姓名和电子邮件字段。
示例强>
为了更清楚,让我来看看你给出的例子。
会议创建者" Jake"在系统上创建一个帐户。
"杰克"创建一个新会议并选择"所有参与者"选项。
only_for_registration
标志设置为false
(因为Jake选择"所有参与者")。"杰克"为" rt 1"创建两种注册类型和" rt 2"。
registration_types
表格中创建两个条目,其中包含conference_id
(来自第2步)和名称。 " rt 1" id
1和" rt 2"与id
2。"杰克"创建一个问题"你的电话号码是什么?"带有文字。
questions
表格中创建一个条目,其中包含问题文本和" conference_id"作为来自step2的id。现在,您可以使用Questions::where("confrence_id", $current_confrence_id)->get()
在confrence编辑页面中显示问题。这是问题表中confrence_id
的用法。"杰克"关联"你的电话号码是什么?"问题仅限于" rt 2"。
registration_type_questions
中添加' question_id' 1(来自步骤4),registration_type_id
2(来自" rt 2"的步骤3)。如果"杰克"选中的问题是强制性的,您可以将required
标记设置为true。在前端" John"进入注册页面并点击"注册"。
"约翰"选择2" rt 1"参与者和2" rt 2"参与者并单击"下一步"。
conference_id
,使用registration_types
oneToMany关系获取所有$conference->registrationTypes
。"约翰"看到表单填写4个用户条目,所有用户条目都有名称和电子邮件字段,2个条目有额外的"你的电话号码是什么?"题。
only_for_registration
标志为false,因此显示所有条目的名称和电子邮件字段。$registation_type->questions
关系获取问题。所以,因为只有2个条目有" rt 2"我们只会显示"您的电话号码是什么?"到2个字段并保留隐藏的question_id
字段。"约翰"填写所有问题的答案,然后单击"下一步"。
如果only_for_registration
标志为真,即"杰克"已选择"仅来自进行注册的用户",然后您只能在第一个条目中显示电子邮件和名称字段。
答案 1 :(得分:0)
如果我正确理解您的问题,您需要一个数据透视表来将问题与多种注册类型相关联(不复制它们)。
此表可以命名为registration_type_question
,并且有两列:
registration_type_id
(已移至questions
),question_id
现在BelongsToMany
和RegistrationType
之间存在Question
关系:
class RegistrationType extends Model
{
public function questions(){
return $this->belongsToMany('App\Question', 'registration_type_question');
}
}