从另一个控制器创建 ActiveRecord 对象 - 我做对了吗? [英] Creating an ActiveRecord object from another controller - am I doing it correctly?

查看:29
本文介绍了从另一个控制器创建 ActiveRecord 对象 - 我做对了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个培训网站,其中有两个模型 UserCourse,它们与第三个模型 CourseCompletions 相关联.第三种模型用于跟踪哪个用户完成了哪些课程,反之亦然.前两个模型有控制器,而第三个没有.

I'm building a training website where I have two models, User and Course, that are associated with a third model, CourseCompletions. The third model is for keeping track of which user has completed which courses and vice versa. The first two models have controllers whereas the third one does not.

我实现了完成课程的功能并且它有效(如果用户之前没有完成该课程,则单击课程页面上的完成课程"按钮会将适当的行插入 course_completion 表中),但我不确定关于我的实现有多健壮和安全.这是在 Course_Controller.rb 中:

I implemented the functionality for completing a course and it works (clicking the "complete course" button on the course page inserts the appropriate row into the course_completion table if the user has not completed that course before), but I'm unsure about how robust and secure my implementation is. This is in 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

我的问题如下:

  1. 我应该像现在一样调用 create ,还是 build(或 create!)更好的选择?
  2. 我应该在该函数中使用强参数吗?如果是这样,在这种特殊情况下我该怎么做?
  1. Should I be calling create like I am doing, or is build (or create!) a better option?
  2. Should I be using strong parameters inside that function? If so, how do I do that in this particular case?

提前致谢.

推荐答案

更改这一行:

 @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 这样的集合创建对象,它仍然是首选方式..

build is just an alias for new, but still the preferred way if you create an object through a collection like : @course.course_completions.build..

create 相当于 .new + .save ,它允许你一次保存一个对象.

create is equivalent to .new + .save, it allow you save an object at one time.

create! 等价于 .new + .save!,与 create 相同不同的是,如果对象不保存,它会抛出异常.

create! is equivalent to .new + .save!, it's the same as create the only difference is that it throws an exception if the object won't save.

在这种情况下您不需要使用强参数,强参数对于表单很重要,可以防止用户更新不允许的字段,假设您有一个包含这些字段的表单:姓名、电子邮件、密码, 在这种情况下,恶意用户可以使用 firebug 动态地向您的表单添加一个字段,例如 admin,然后他将该字段设置为 true,这是一个如果您的数据库中有一个名为 admin 的字段,则会出现安全问题,因此为了防止用户设置此字段(通常不在您的表单中),我们使用强参数来仅指定我们允许的字段用户更新.

you don't need in this case to use strong parameters, strong parameters are important with forms to prevent the user updating non permitted fields, imagine you have a form with these fields : name, email, password, in this case a malicious user can add a field dynamically to your form using firebug for example let say admin, then he set the field to true, this is a security problem if you have a field called admin in your database, so to prevent the user to set this field (which normally is not in your form) we use strong parameters to specify only the fields we allow the user to update.

更新:

回答您对上述 3 个代码部分之间差异的评论:

to answer your comment about the difference between the 3 code parts above :

它们之间没有区别,但是如果你想让两者相同,要么你写user_id:@user.id,要么写user:@user,Rails 很聪明地理解您要设置外键 user_id.

there is no difference between them, but if you want the two first are the same, either you write user_id: @user.id or user: @user, Rails is smart to understand that you want to set the foreign key which is user_id.

第三个只是不同的语法或变体,而不是从模型 Course_completion 创建一个新对象,然后插入 user_idcourse_id就像我们在前两个示例中所做的那样,您只需根据集合创建一个新对象,我的意思是集合您的course_completions",因为您的 @course has_many course_completions(可以说@course 有一个名为course_completions的集合)

the third is just a different syntax or variation, instead of create a new object from the model Course_completion then insert the user_id and course_id like we did in the two first example, you have just to create a new object based on a collection, i mean by collection your "course_completions", so because your @course has_many course_completions (you can say that @course has a collection called course_completions)

要将新对象添加到您的course_completions集合"中,您只需编写@course.course_completions.build,然后传递user_idcompletion_date 值,但是 course_id 值呢?答案是你的集合已经基于@course (@course.course_completions),所以你不需要设置 course_id,Rails 知道它.

to add a new object to your course_completions "collection" you have just to write @course.course_completions.build, then you pass the user_id and completion_date values to it, but what about course_id value ? the answer is that your collection is already based on @course (@course.course_completions) so you don't need to set the course_id, Rails know about it.

希望对您有帮助

这篇关于从另一个控制器创建 ActiveRecord 对象 - 我做对了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆