如何建模此上下文以便创建自定义问题和收集答案?

时间:2018-03-05 17:41:47

标签: php database laravel database-design laravel-eloquent

上下文

当用户(会议创建者)创建会议时,他可以为该会议创建注册表单。因此,他访问页面“http://proj.test/conference/edit/1/questions”以将表单编辑为ID为1的会议。

在此页面中,他可以通过复选框将现有问题与每种注册类型相关联。他还可以点击“添加自定义问题”,向表单添加更多自定义问题。

例如,他可以创建一个自定义问题“你的电话号码是什么?”并且可以将此问题与例如“通用”的注册类型或之前创建的任何其他所有注册类型相关联。

因此,当会议创建者访问“http://proj.test/conference/edit/1/questions/create”时,他可以访问表单,为ID为1的会议创建新的自定义问题。

在此表单中,用户(会议创建者)需要选择问题的标题(例如:电话号码)和问题类型(例如:文本),然后单击“存储问题”。

问题类型字段是一个包含5个选项的选择菜单(文本,长文本,单选按钮,选择菜单和复选框)。 如果用户选择问题类型作为单选按钮,则选择菜单或复选框会显示一些文本输入,以便用户可以插入每个选项的值。

enter image description here

然后在用户进行注册的前端,例如用户John在注册类型“Rt 001”中注册了2个参与者,他和Jake,所以他需要填写表格,在此例如,他需要填写每个参与者的字段,因为会议创建者选择了“从所有参与者收集信息”选项。注册表始终询问进行注册的用户的姓名和电子邮件,但在这种情况下,注册表还会询问用户“您的电话号码是什么”,因为会议创建者创建的此字段由会议关联用户正在注册的注册类型的创建者(Rt 001):

enter image description here

疑惑:

我对如何根据表,列和关系组织这个上下文以正确建模这些部分有一些疑问:

  • 部分可以创建自定义问题,如果该字段是强制性的,则存储
  • 以后用户在会议的一种或多种注册类型中进行会议注册时收集答案的部分
  • 会议创建者选择可以选择的部分可以选择从所有参与者收集数据,也可以只为进行注册的用户收集数据

//会议模型

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

2 个答案:

答案 0 :(得分:1)

根据我从问题和讨论中获得的信息,我进行了架构更改。注意:在此模式中,我使用laravel使用的命名标准(默认情况下)。像多个表名一样,主键将是' id'等

enter image description here

大部分内容与问题中的架构类似。我会解释一下,

  • 用户 - 包含会议创建者的表格。
  • 会议 - conference,created_user_id是创建它的用户。
  • registration_types - 保存其所属会议的注册类型和conference_id链接。
  • 问题 - 通过conference_id显示哪些会议问题属于
  • registration_types 数据透视表,用于保存注册类型以进行问题制图。
  • 注册 - 包含注册信息的表。
  • 参与者 - 为具有姓名和电子邮件字段的参与者保留条目。每个参与者都有单独的registration_type。
  • 答案 - 保留每位参与者给出的答案。它有question_id来表明哪个问题& participant_id表示它属于哪个参与者。

上述架构为每种注册类型添加了required选项,因此您可以在一种类型中强制提出问题,而在另一种类型中不强制使用。必填字段已添加为extra attributeregistration_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,则表示您不会向其他参与者显示姓名和电子邮件字段。

示例

为了更清楚,让我来看看你给出的例子。

  1. 会议创建者" Jake"在系统上创建一个帐户。

    • 我们将在用户表中创建一个包含必要帐户字段的条目。
  2. "杰克"创建一个新会议并选择"所有参与者"选项。

    • 在会议桌中创建一个新条目,其名称和only_for_registration标志设置为false(因为Jake选择"所有参与者")。
  3. "杰克"为" rt 1"创建两种注册类型和" rt 2"。

    • registration_types表格中创建两个条目,其中包含conference_id(来自第2步)和名称。 " rt 1" id 1和" rt 2"与id 2。
  4. "杰克"创建一个问题"你的电话号码是什么?"带有文字。

    • questions表格中创建一个条目,其中包含问题文本和" conference_id"作为来自step2的id。现在,您可以使用Questions::where("confrence_id", $current_confrence_id)->get()在confrence编辑页面中显示问题。这是问题表中confrence_id的用法。
  5. "杰克"关联"你的电话号码是什么?"问题仅限于" rt 2"。

    • registration_type_questions中添加' question_id' 1(来自步骤4),registration_type_id 2(来自" rt 2"的步骤3)。如果"杰克"选中的问题是强制性的,您可以将required标记设置为true。
  6. 在前端" John"进入注册页面并点击"注册"。

  7. "约翰"选择2" rt 1"参与者和2" rt 2"参与者并单击"下一步"。

    • 由于我们来自会议页面,我们已经conference_id,使用registration_types oneToMany关系获取所有$conference->registrationTypes
    • 一旦约翰按下"接下来"您可以将此信息保存在会话中或前端本身。由于未提供用户信息,因此无需在此阶段提交数据库。
  8. "约翰"看到表单填写4个用户条目,所有用户条目都有名称和电子邮件字段,2个条目有额外的"你的电话号码是什么?"题。

    • 默认情况下,仅显示第一个条目的名称和电子邮件,但由于only_for_registration标志为false,因此显示所有条目的名称和电子邮件字段。
    • 对于每个条目,使用$registation_type->questions关系获取问题。所以,因为只有2个条目有" rt 2"我们只会显示"您的电话号码是什么?"到2个字段并保留隐藏的question_id字段。
    • 或者,对于所有条目,让用户在他选择的注册类型之间切换。通过这种方式,他可以灵活地选择第一个参与者,即他自己是rt2。
  9. "约翰"填写所有问题的答案,然后单击"下一步"。

    • 在"注册"中创建一个条目表
    • 循环执行步骤8中的所有条目。
      • 在参与者表格中创建一个条目,其中包含来自step8的registration_id,registration_type值以及电子邮件和姓名。如果其他用户不需要,请将电子邮件和名称保留为空。
      • 如果问题是自定义问题,请在答案表中创建一个条目,其中包含最后一个参与者ID和隐藏的question_id字段。
  10. 如果only_for_registration标志为真,即"杰克"已选择"仅来自进行注册的用户",然后您只能在第一个条目中显示电子邮件和名称字段。

答案 1 :(得分:0)

如果我正确理解您的问题,您需要一个数据透视表来将问题与多种注册类型相关联(不复制它们)。

此表可以命名为registration_type_question,并且有两列:
registration_type_id(已移至questions),question_id

现在BelongsToManyRegistrationType之间存在Question关系:

class RegistrationType extends Model
{
    public function questions(){
        return $this->belongsToMany('App\Question', 'registration_type_question');
    }
}