王梦琪的博客

记录技术学习及感悟

第六周的大坑

| Comments

xdite老师分享说有把自己之前实现问题的整个过程都记录下来,不仅记录对的还有记录错的,好处是:

  1. 帮助攻克难题:方便查看之前的步骤,避免步骤太多忘记之前的思路和尝试的方法。
  2. 避免以后犯同样的错误:错的东西一旦记录下来以后会犯得可能性大大降低了。
  3. 便于回顾:以后可以回顾自己是如何解决问题的,回顾当时的思路和方法。
  4. 可以帮助遇见相同问题的开发者。

实现步骤

本周有一半时间在做前端,前端的坑主要还是排版的问题,这里记录一个后端的功能。

功能:admin创建一个项目的时候通过输入user的email的方式指定用户(说明是哪个用户创建的)。

我的想法是:admin在新建项目页输入email提交时,将email参数传入controller,在数据库里找对应的user_id,找到了就将user_id存到project表里,找到后进行其他栏位的判断,找不到在当前页面报错。

步骤

  1. 第一步:在view里使用simple_form将email这个参数传到controller
    因为在project这个model里没有email字段,所以google ”rails simple form not",此时出现最佳匹配句“rails simple form field not in model”
    找到用法:在model里添加attr_accessor:user_email, 在view里就可以写<%= f.input :user_email %>

  2. 第二步:在controller里取出email的对应value,并进行判断。
    第一稿:

    def create
    @project = Project.new(project_params)
    @user = User.where(email: params[:user_email])
    if !@user.present?
      render :new
      flash[:alert] = "无此用户"
    else
      @project.user = @user
      if @project.save
        redirect_to admin_projects_path
      else
        render :new
      end
    end
    end
    

    此时出现坑
    使用:@user = User.where(email: params[:user_email])
    取不出来user_email参数,去看rails log 出现:

    <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"kAzFJ7l7dzx9j+pZxlQbNT+9CEexlmT/ 6wfjRgL6w5hZmOKt+R/ep6KVuC8M9se46fapQ1UIyy53sMlNXvSDJA==", "project"=><ActionController::Parameters   {"name"=>"22", "description"=>"<p>22</p>", "user_email"=>"1", "category_id"=>"1", "fund_goal"=>"33",     "video"=>"3"} permitted: false>, "commit"=>"创建项目", "controller"=>"admin/projects",  "action"=>"create"}
    

    发现是hash套hash结构,应该现将:project对应的value取出,再将:user_email对应的value取出。如下:
    @user = User.where(email: params[:project][:user_email])
    此时又发现
    报错AssociationTypeMismatch @project.user = @user
    使用binding.pry发现可以取出@user,但是取不出 @user.email.看来是数据类型不对,发现使用where得到的是一个array,而使用 find_by得到的是一个值。
    在rails log里 使用where是

    SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 1],
    

    而使用find_by得到的是

    SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 1]    ["LIMIT", 1]]
    

    至此出了第二稿,正确。

     def create
    @project = Project.new(project_params)
    @user = User.where(email: params[:project][:user_email])
    if !@user.present?
      render :new
      flash[:alert] = "无此用户"
    else
      @project.user = @user
      if @project.save
        redirect_to admin_projects_path
      else
        render :new
      end
    end
    end
    

Comments

comments powered by Disqus