Ege*_*soz 3 ruby-on-rails ruby-on-rails-4
我正在建立一个培训网站,我有两个模型,User并且Course与第三个模型相关联,CourseCompletions.第三个模型用于跟踪哪个用户已完成哪些课程,反之亦然.前两个型号有控制器,而第三个型号没有.
我实现了完成课程的功能并且工作正常(单击课程页面上的"完整课程"按钮,如果用户之前没有完成该课程,则将相应的行插入course_completion表中),但我不确定其有多强大并确保我的实施安全.这是在Course_Controller.rb中:
为简洁省略了辅助方法
def complete_course
@course = current_course
@user = current_user
if !already_completed
@course.course_completions.create(user_id: @user.id, course_id: @course.id, completion_date: Time.now)
flash[:success] = "Congratulations! Your progress has been saved."
redirect_to course_path
else
flash[:success] = "Looks like you have already completed this course before, but mad props for reviewing it!"
redirect_to course_path
end
end
Run Code Online (Sandbox Code Playgroud)
我的问题如下:
先感谢您.
改变这一行:
@course.course_completions.create(user_id: @user.id, course_id: @course.id, completion_date: Time.now)
Run Code Online (Sandbox Code Playgroud)
至
Course_completion.create(user_id: @user.id, course_id: @course.id, completion_date: Time.now)
Run Code Online (Sandbox Code Playgroud)
或者
Course_completion.create(user: @user, course: @course, completion_date: Time.now)
Run Code Online (Sandbox Code Playgroud)
或者
@course.course_completions.build(user: @user, completion_date: Time.now) # you can also use new instead of build, but build is preferred in this case
Run Code Online (Sandbox Code Playgroud)
build只是一个别名new,但如果你通过一个集合创建一个对象,仍然是首选方式:@course.course_completions.build..
create相当于.new+ .save,它允许您一次保存一个对象.
create!等价于.new+ .save!,它的create唯一区别在于,如果对象不能保存,它会抛出异常.
在这种情况下你不需要使用强参数,强大的参数对于防止用户更新非允许字段的表单很重要,想象你有一个包含以下字段的表单:名称,电子邮件,密码,在这种情况下恶意用户可以使用firebug动态地向表单添加一个字段,例如admin,然后将字段设置为true,如果您的数据库中有一个名为admin的字段,则这是一个安全问题,因此要阻止用户设置此字段(通常不在您的表单中)我们使用强参数来仅指定允许用户更新的字段.
更新:
回答您对上述3个代码部分之间差异的评论:
它们之间没有什么区别,但如果你想在两个第一是相同的,无论是你写的user_id: @user.id还是user: @user,Rails是一个聪明,明白你想设置的外键是user_id.
第三个只是一个不同的语法或变体,而不是从模型创建一个新的对象Course_completion然后插入user_id和course_id我们在第一个例子中做的一样,你只需要创建一个基于集合的新对象,我的意思是通过集合你的"course_completions",因为你的@course has_many course_completions(你可以说@course有一个名为course_completions的集合)
要在你刚编写的course_completions"集合"中添加一个新对象@course.course_completions.build,然后将user_id和completion_date值传递给它,但是course_id值呢?答案是你的收藏已经基于@course(@ course.course_completions),所以你不需要设置course_id,Rails就知道了.
希望这有帮助
| 归档时间: |
|
| 查看次数: |
2656 次 |
| 最近记录: |