从另一个控制器创建一个ActiveRecord对象 – 我正确地做了吗?
我正在建立一个培训网站,我有两个模型, User
和Course
,与第三个模型, CourseCompletions
相关联。 第三个模型用于跟踪哪个用户已完成哪些课程,反之亦然。 前两个型号有控制器,而第三个型号没有。
我实现了完成课程的function并且它有效(点击课程页面上的“完整课程”按钮,如果用户之前没有完成该课程,则将相应的行插入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
我的问题如下:
- 我应该像我正在做的那样调用create,还是构建(或创建!)更好的选择?
- 我应该在该function中使用强参数吗? 如果是这样,我在这种特殊情况下如何做到这一点?
先感谢您。
改变这一行:
@course.course_completions.create(user_id: @user.id, course_id: @course.id, completion_date: Time.now)
至
Course_completion.create(user_id: @user.id, course_id: @course.id, completion_date: Time.now)
或者
Course_completion.create(user: @user, course: @course, completion_date: Time.now)
或者
@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
build
只是new
的别名,但如果你通过如下集合创建一个对象仍然是首选方法: @course.course_completions.build..
create
等同于.new
+ .save
,它允许您一次保存一个对象。
create!
相当于.new
+ .save!
,它与create
相同,唯一的区别是如果对象无法保存则抛出exception。
在这种情况下,您不需要使用强参数 ,强大的参数对于表单来说非常重要,以防止用户更新非允许的字段,想象您有一个包含以下字段的表单: 名称,电子邮件,密码,在这种情况下恶意用户可以使用firebug动态地向表单添加一个字段,例如admin ,然后将字段设置为true,如果您的数据库中有一个名为admin的字段,则这是一个安全问题,因此要阻止用户设置此字段(通常不在您的表单中)我们使用强参数来仅指定允许用户更新的字段。
更新:
回答您对上述3个代码部分之间差异的评论:
它们之间没有区别,但如果你想要的两个是相同的,要么你写user_id: @user.id
或user: @user
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值呢? 答案是你的collections已经基于@course( @ course.course_completions ),所以你不需要设置course_id,Rails知道它。
希望这有帮助
- Django相当于“rake rails:freeze:gems”和“rake gems:unpack”
- 使用plupload和Rails 3的Amazon S3 Multipart上传
- 缺少`secret_token`和`secret_key_base`用于’开发’环境,在`config / secrets.yml中设置这些值
- Rails link_to带有样式glyphicon的标记标记
- 在Rails 5.0.0.beta3,-api选项中使用accepts_nested_attributes_for时出现问题
- 轨道unit testing是否应该打到数据库?
- ActiveRecord按外部数组排序
- 将CSV导入添加到ROR应用程序
- Active Admin Gem – Rails 3.2.3,Heroku错误日志