Giter VIP home page Giter VIP logo

homeworkapp's Introduction

Hi there 👋.

Current is the future.

Utilities

homeworkapp's People

Contributors

arlyxiao avatar ben7th avatar

Watchers

 avatar

homeworkapp's Issues

review 2012/04/09/18

StudentController show 中

@student = current_user.homework_assigns.find_by_homework_id(params[:id])
#@student 这个变量名字好穿越-_-!

user.uploaded_count(homework) 方法
因为 user 上会有很多业务模块上的方法,防止混乱,名字的意思要表达清楚
比如 user.uploaded_student_upload_count_of_homework(homework)


StudentController create 中

@homework_assign = current_user.homework_assigns.find_by_homework_id(params[:homework_assign][:homework_id])
@homework_assign.content = params[:homework_assign][:content]
@homework_assign.is_submit = true
@homework_assign.has_finished = true
@homework_assign.submitted_at = DateTime.now

可以封装模型方法

   class Homework
     def submit_by_user(user,content = "")
       homework_assign = self.homework_assigns.find_by_user_id(user.id)
       homework_assign.content = content
       homework_assign.is_submit = true
       homework_assign.has_finished = true
       homework_assign.submitted_at = DateTime.now
       homework_assign.save
     end
   end

   # controller 调用
   homework = Homework.find(params[:homework_assign][:homework_id])
   homework.submit_by_user(current_user,params[:homework_assign][:content])

教师的作业附件打包和学生的作业附件打包在流程上统一为点击下载时去打包

在这个流程基础上,尽量把代码抽取成模型上的一些小方法,阅读起来不至于很疲劳
以后优化流程时,也更好想

一些编码规范的问题

关于老师和学生模型的逻辑

用户模型和老师模型
用户模型和学生模型
是一对一关联的用 has_one

关于怎么判断一个用户是学生和老师可以给用户增加这两个方法 is_student? is_teacher?

加入角色判断后,可以
1 把权限校验加到作业模型上(只有老师可以布置作业)

2 首页也可以根据此来放不同的导航
老师是 我布置的作业列表链接
学生是 我需要完成的作业列表链接

homework 上加一个表示作业期限的字段,精确到天

我的思路是 用 integer 类型来表示 比如 今天用 20120319 表示
这样的好处是
 1)便于 按 日期去查找某一天作业
 2) 便于查找某一天以前或以后的作业 

查询起来比用日期字段要简单
或者有什么更好的方法(咱们讨论)

homework review 2012/04/09

数据库的修改

作业分配模型 homework_assigns

creator_id 有些穿越,建议修改为 user_id 表示被分配给的人

教师上传的作业附件模型 homework_teacher_attachements

建议去掉 creator_id,教师附件必定是 创建 homework 的教师上传的

教师要求学生上传的附件约束条件模型 homework_student_attachements

1 建议去掉 creator_id,约束条件必定是 创建 homework 的教师创建的
2 模型建议改名为 homework_student_upload_requirements,意思更直白

学生上传的作业附件 homework_student_uploads

homework_student_attachements 改名为 homework_student_upload_requirements 后
该表的 attachement_id 字段建议改为 requirement_id

说明

数据库表和字段的命名很重要,要尽量直白,不让人产生歧义
homework_student_attachements 这个表名就让我产生了歧义


关于 homework.assigned_by_student(student) 方法的修改

原来的实现

  def assigned_by_student(student)
    HomeworkAssign.where(:homework_id => self.id, :creator_id => student.id).first
  end

建议的实现

  def assigned_by_user(user)
    self.homework_assigns.where(:creator_id => user.id).first
  end

说明

1 homework.homework_assigns.where(conditions) 比 HomeworkAssign.where(conditions)
个人认为代码更容易阅读
2 提这个修改建议,为了加深你对 has_many 的使用和理解,习惯在 has_many 声明的方法调用后增加
conditions 的这种查询方式,用这种方式编写的查询代码更容易阅读
3 student 是一个已经存在的模型,而这里参数应该是一个 user 模型,所以方法名和参数名建议用 user,防止穿越


undeadline_homeworks deadline_homeworks 两个 has_many 声明,有一些问题

两个 has_many 在下边两个 module 里分别声明了一次
Homework::UserMethods
HomeworkAssign::UserMethods
会造成其中一个覆盖另一个
需要改成不相同的名字,才能不冲突

说明

系统会给 user 模型增加很多方法和 has_many 声明,所以命名时要注意,不要出现 命名一样导致被覆盖的问题


HomeworkStudentAttachement 中声明的 user.has_many :homework_student_attachements

需要加 foreign_key=> :creator_id


下面三个修改是一个整体,完全看完后,才能明白我要表达的意思

关于 HomeworkStudentUpload.find_current(creator_id, attachement_id) 的修改

原来的实现

  class HomeworkStudentUpload < ActiveRecord::Base
    def self.find_current(creator_id, attachement_id)
        HomeworkStudentUpload.where(:creator_id => creator_id, :attachement_id => attachement_id).first
    end
  end

建议的实现

  class HomeworkStudentAttachement < ActiveRecord::Base
    def upload_of_user(user)
      self.homework_student_uploads.where(:creator_id => user.id).first
    end
  end

说明

1 这个修改遵循的原则是,根据业务逻辑把方法放到最相关的模型上,尽量用实例方法,其次才用静态方法
这样做使代码调用,更接近自然语言,更容易阅读和维护:)
2 参数建议传模型,而不是模型ID
因为,现在的逻辑很简单,只需要一个ID就可以,但是如果以后扩展需要模型的其他属性呢?
遵循面向对象**,参数传递模型,好处多多,养成好的编码习惯是很必要的


关于 user.is_upload_homework_attachement(attachement_id) 方法的修改

原来的实现

  class User < ActiveRecord::Base
    def is_upload_homework_attachement(attachement_id)
      HomeworkStudentUpload.where(:creator_id => self.id, :attachement_id => attachement_id).exists?
    end
  end

建议的实现

  class User < ActiveRecord::Base
    def is_upload_homework_attachement?(attachement)
      user.homework_student_uploads.where(:attachement_id => attachement.id).exists?
    end
  end

说明

1 还是那句话-_-!,为了加深你对 has_many 的使用和理解
用 has_many + conditions 的查询方式,代码更容易阅读
在这里,可以一眼看出从 user 的 homework_student_uploads 中查找某些东西
2 如果方法返回布尔类型,建议方法结尾加问号
3 参数传模型,而不是模型ID...


以上两个建议是为了演示一些编码原则,结合业务逻辑的话,还需要一点修改

  # 这个方法是找到某个用户对某个约束是否提交了附件
  user.is_upload_homework_attachement?(attachement)

  # 这个方法是找到某个用户对某个约束提交的附件
  homework_student_attachement.upload_of_user(user)

两个方法其实类似

建议的修改

  class HomeworkStudentAttachement < ActiveRecord::Base
    def upload_of_user(user)
      self.homework_student_uploads.where(:creator_id => user.id).first
    end

    def is_uploaded_of_user?(user)
      !upload_of_user(user).blank?
    end
  end

说明

1 如果方法返回布尔值,建议方法结尾加问号...
2 多个方法里的逻辑类似的时候,可以一个调用另一个,这样逻辑变更的时候,只需要修改一个地方就可以了

只要符合 第2点,你也可以把两个方法全部定义在 user 模型上,像这样

user.homework_student_upload_of_attachment(attachement)

user.is_uploaded_of_attachment?(attachement)

或者

homework_student_attachement.upload_of_user(user)

user.is_uploaded_of_attachment?(attachement)


总结几个主要问题

尝试习惯面向对象

比如把方法声明在最相关的模型上,尽量用实例方法,其次才是静态方法,静态方法更像是面向过程的风格

参数传递模型,而不是模型ID

熟练使用 has_many,包括

has_many 的声明方法,包括 through conditions class_name foreign_key 等等这些支持的参数的使用

熟悉 has_many 声明生成的方法,这类方法返回的值是一个类似数组的对象,上面除了 each map 这些类似数组的方法,还有 exists? where build 这些方法

使用 has_many 声明生成的方法,去写查询代码,更容易阅读,编码也不容易出现低级错误


最后再次吐槽

赶紧把 homework_student_attachements 改名 homework_student_upload_requirements 吧,reveiw 时,我都要晕掉了,太穿越了!!!!!

  |--------| ------------- -----------
  |        |       |                 | 
  |        |       |               |
  |        |       |             |
  |        |       |           |         
  |        |       |         |   
  |        |       |       |
  |--------|       |      -------------

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.