【问题标题】:Rails - feedback on specific users, how to set up the form to identify relevant usersRails - 对特定用户的反馈,如何设置表单来识别相关用户
【发布时间】:2023-03-26 23:53:01
【问题描述】:

在过去的几个月里,我一直在尝试弄清楚如何建立一个评估模型,以便一些用户可以在他们的联合项目中评估其他用户。

我之前问过这个问题,但后来有人建议让这个模型多态的建议不是正确的方法。我实际上无法获得这篇文章中的建议,但我的问题现在略有不同。

http://stackoverflow.com/questions/36394489/rails-4-polymorphic-associations-and-concerns

我有一个用户模型和一个评估模型。

用户

has_many :given_evaluations, foreign_key: :evaluator_id, dependent: :destroy, class_name: Evaluation
  has_many :received_evaluations, foreign_key: :evaluatee_id, dependent: :destroy, class_name: Evaluation

评估

belongs_to :evaluator, foreign_key: :evaluator_id, class_name: User
  belongs_to :evaluatee, foreign_key: :evaluatee_id, class_name: User

我现在正试图弄清楚如何设置表单,以便正确的用户获得评估并限制哪些用户可以留下反馈。

在评估表中,我有:

<%= simple_form_for(@evaluation) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :overall_score, collection: 1..10, autofocus: true, :label => "How do you rate this project experience (1 being did not meet expectations - 10 being met all expectations) ?" %>
    <%= f.input :project_score, collection: 1..10, :label => "How successful was the project (1 being did not meet expectations - 10 being met all expectations)?"   %>
    <%= f.input :continue_project?, as: :boolean, checked_value: true, unchecked_value: false, :label => "Do you intend to continue working on the project?" %>
    <%= f.input :remark, as: :text, :label => "Evaluate your project experience", :input_html => {:rows => 10}  %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

在我的评估控制器中,我有:

class EvaluationsController < ApplicationController
  before_action :set_evaluation, only: [:show, :edit, :update, :destroy]
  # before_filter :get_user, only: [:show, :edit, :update, :destroy]

  # GET /evaluations
  # GET /evaluations.json
  def index
    @evaluations = Evaluation.all
  end




  # GET /evaluations/1
  # GET /evaluations/1.json
  def show
    @received_evaluations = @user.received_evaluations
  end

  # GET /evaluations/new
  def new
    @evaluation = Evaluation.new
  end

  # GET /evaluations/1/edit
  def edit
  end

  # POST /evaluations
  # POST /evaluations.json
  def create
    @evaluation = Evaluation.new(evaluation_params)

    respond_to do |format|
      if @evaluation.save
        format.html { redirect_to @evaluation, notice: 'Evaluation was successfully created.' }
        format.json { render :show, status: :created, location: @evaluation }
      else
        format.html { render :new }
        format.json { render json: @evaluation.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /evaluations/1
  # PATCH/PUT /evaluations/1.json
  def update
    respond_to do |format|
      if @evaluation.update(evaluation_params)
        format.html { redirect_to @evaluation, notice: 'Evaluation was successfully updated.' }
        format.json { render :show, status: :ok, location: @evaluation }
      else
        format.html { render :edit }
        format.json { render json: @evaluation.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /evaluations/1
  # DELETE /evaluations/1.json
  def destroy
    @evaluation.destroy
    respond_to do |format|
      format.html { redirect_to evaluations_url, notice: 'Evaluation was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_evaluation
      @evaluation = Evaluation.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def evaluation_params
      params[:evaluation].permit(:overall_score, :project_score, :personal_score, :remark, :work_again?, :continue_project?)
    end
end

我的控制器操作是否正确?我是否需要在控制器中放置一些东西来识别哪个用户正在接受评估以及哪个用户正在给出评估。我是否需要在评估控制器中将 :user_id 添加到允许的参数中?

如何更改表单以识别正在接受评估的正确用户。

我的路线是:

resources :evaluations

 devise_for :users, #class_name: 'FormUser',
             :controllers => {
                :registrations => "users/registrations",
                # :omniauth_callbacks => "users/authentications"
                :omniauth_callbacks => 'users/omniauth_callbacks'

           }

  # get '/auth/:provider/callback' => 'users/authentications#create'
  # get '/authentications/sign_out', :to => 'users/authentications#destroy' 

  # PER SOURCEY TUTORIAL ----------
  match '/users/:id/finish_signup' => 'users#finish_signup', via: [:get, :patch], :as => :finish_signup

工作流程

  1. 用户创建项目(所有者)
  2. 业主邀请同学加入项目(队友)
  3. 如果队友在截止日期前接受,则参与项目的用户完成项目。
  4. 一旦完成,每个用户都会评估参与项目的其他用户和项目本身。为此,项目中涉及的每个用户都会在其用户页面上看到一个按钮,以获取指向评估表的链接。我需要弄清楚如何为团队成员以及他们从事的项目引用其他用户 ID。

我没有将评估路线嵌套在用户路线中的原因是我可能会尝试(如果我能先弄清楚这部分)将项目评估与队友评估分开,在这种情况下,我想将评估用于两个目的。我稍后再谈。目前,评估模型是针对用户的。

最后,我使用 devise gem 进行用户身份验证。

识别被评估者的问题

采纳 Paul 关于如何识别评估 ID 的建议,我将此选择添加到我的评估表中:

<%= f.select :evaluatee_id, User.all.map{|u| [u.formal_name]} %>

Paul 建议在这一行的 [] 中包含 u.id。我不明白所有部分如何在这行代码中组合在一起(或 map 的含义),但我会再次尝试分别找到这些问题的解释。我删除了 u.id,因为我收到了下面的错误(事实证明,删除它仍然会导致下面的错误):

Couldn't find Evaluation with 'id'=7 [WHERE "evaluations"."evaluatee_id" = ?]

我可以从控制台看到评估正在保存,但它没有记录评估者ID。

Evaluation.last
  Evaluation Load (10.3ms)  SELECT  "evaluations".* FROM "evaluations"  ORDER BY "evaluations"."id" DESC LIMIT 1
 => #<Evaluation id: 7, evaluatee_id: 0, overall_score: nil, project_score: nil, personal_score: nil, remark: "edededededede", work_again?: nil, continue_project?: nil, created_at: "2016-06-10 02:08:44", updated_at: "2016-06-10 02:08:44", evaluator_id: 34> 

错误消息指向我的评估控制器中的显示操作,它具有:

def show
    # @received_evaluations = @user.received_evaluations

    @received_evaluation = current_user.received_evaluations.find params[:id]
  end

【问题讨论】:

  • 还请提供您的路线 (routes.rb) 以了解评估表单的范围 - 它是用户的嵌套资源还是独立的? URL 是控制器 /evaluations/1 中的注释还是 /users/:id/evaluations/1?
  • 同样,描述创建评估的逻辑(工作流程)。我是否打开所有用户的列表,然后打开单个用户的所有项目,然后创建评估?或者我有所有项目的清单吗?我究竟在哪里按下“评估”按钮来创建新的评估?到目前为止,在 new 和 create 控制器操作上,您都创建了新的未绑定评估,既与当前用户(给出评估的人)无关,也与评估的用户(您给出评估的人)无关
  • 定义进行评估的用户取决于您的身份验证解决方案 - 您如何管理用户、登录、会话。例如。如果你使用 devise 那么你有 current_user helper

标签: ruby-on-rails associations


【解决方案1】:

我同意多态关联在这里是错误的方法。

您应该在 #create 方法中执行此操作,以使用正确的评估者自动记录评估:

def create
  # change this: @evaluation = Evaluation.new(evaluation_params)
  # to this:
  @evaluation = current_user.given_evaluations.build(evaluation_params)

  # ... the rest is fine as-is ...      
end

current_user 来自 Devise,返回当前登录的任何用户。

我还要确保#update 确实是current_user.given_evaluations.find(params[:id]),这样你就不能更改你没有写的评估。 #destroy 也一样。

根据您的要求,您可能希望以类似的方式访问其他方法。

您的 #show 方法在我看来是错误的。它应该只找到一个评估:

def show
  @received_evaluation = current_user.received_evaluations.find params[:id]
end

另外,#index 的范围可能应该是当前用户。可能您想显示您给予的评价以及您收到的评价:

def index
  @given_evaluations = curent_user.given_evaluations
  @received_evaluations = curent_user.received_evaluations
end

编辑:要设置evaluatee_id,只需像传递任何其他参数一样传递它。首先,允许它来自前端:

def evaluation_params
  params[:evaluation].permit(
    :overall_score, :project_score, :personal_score,
    :remark, :work_again?, :continue_project?, :evaluatee_id)
end

然后在您的表单中添加一个小部件,让用户提供它。例如,它可以是列出所有用户的&lt;select&gt;

<%= f.select :evaluatee_id, User.all.map{|u| [u.id, u.name]} %>

这将生成类似这样的 HTML:

<select name="evaluation[evaluatee_id]">
  <option value="1">Joe</option>
  <option value="2">Sarah</option>
  <option value="3">Fred</option>
</select>

在上面,123 是您可以选择评估的用户的 ID。每个&lt;option&gt; 的内容都是他们的名字。浏览器将提交您选择的任何评估者的选项值(ID)。

当然,您应该将u.name 更改为您实际用于命名用户的任何列/方法,例如emailfull_name 或其他。此外,您可能还想对列表进行排序和过滤——只要适合您的应用即可。

另请注意,使用&lt;select&gt; 只是一种选择。您可以让评估者在前一页上选择被评估者,然后将其作为隐藏字段通过表单传递。或者任何你喜欢的!重点是只要前端发送evaluation[evaluatee_id],就可以像其他参数一样保存。

【讨论】:

  • 嗨,保罗。我试过了 - 谢谢你的建议。我收到评估控制器的错误,上面写着:找不到带有 'id'=5 [WHERE "evaluations"."evaluatee_id" = ?] 的评估,它引用了您向我展示的创建操作中的行。我真的被困住了。我认为表格有问题。我不知道如何确定谁是评估的接受者,我认为该表格与该问题有关。
  • 我可以从控制台看到评估已创建。 evaluator_id 设置为当前用户 ID。然而,evaluate_id 没有设置。你知道如何设置吗?
  • 您将需要以某种方式获取被评估者的 ID。你觉得这个流程是什么样的?我假设您将有另一个视图,其中用户选择他们正在评估的人并单击提交。然后 evaluatee_id 作为参数发送到 create 操作,作为 evaluatee_id。
  • 我同意@ruby_newbie。可能您可以在评估表中有一个&lt;select&gt; 下拉菜单来选择evaluatee_id
  • 怎么设置被评估者id?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 2020-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多