【问题标题】:Rails: Best Practice for Hidden FieldsRails:隐藏字段的最佳实践
【发布时间】:2017-03-14 03:56:22
【问题描述】:

我真的很困惑何时使用隐藏字段。

我在提交表单时尝试传递 user_id,除了:

<%= f.hidden_field :user_id %> 

但是,我知道这是错误的。我已将模型设置为属于用户,但据我所知,这不会自动分配 ID。

有人能指出正确的方向吗?

编辑:感谢大家的回复。正如我之前所说,我知道您不应该将 hidden_​​field 用于 ID 之类的重要内容。根据链接@brad-werth 的帖子,这样分配质量太容易了。

我正在添加代码以使这个问题更容易回答。我需要提交下面的表格并确保它已分配给用户。另外,是的,我正在使用 Devise:

votes_controller.rb

class VotesController < ApplicationController
  before_action :set_vote, only: [:show, :edit, :update, :destroy]

# GET /votes
# GET /votes.json
def index
  @votes = Vote.for_user(current_user).where(nil)
end

# GET /votes/1
# GET /votes/1.json
  def show
   redirect_to action: "index"
  end

# GET /votes/new
 def new
  @vote = Vote.new

  if @vote.save
    user_id = current_user.id
  else
    render 'new'
  end
 end

_form.html.erb

<%= form_for(vote) do |f| %>
  <% if vote.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(vote.errors.count, "error") %> prohibited this vote from being saved:</h2>

      <ul>
        <% vote.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

<div class="field">
  <%= f.label :widget %>
  <%= f.text_field :widget_name, data: {autocomplete_source: widgetnames_path} %>
</div>

<div class="">
  <!-- description will go here -->
</div>

<div class="field">
  <%= f.label :originality %>
  <%= f.number_field :originality %>
</div>

<div class="field">
  <%= f.label :interest %>
  <%= f.number_field :interest %>
</div>

<div class="field">
  <%= f.label :rating %>
  <%= f.number_field :rating %>
</div>

<div class="field">
  <%= f.label :comments %>
  <%= f.text_field :comments %>
</div>

<div class="actions">
  <%= f.submit %>
</div>
<% end %>

【问题讨论】:

  • 你能提供更多关于你使用的表格的细节
  • 您好,欢迎来到 Stack Overflow。您能否提供一些支持代码,例如控制器操作(呈现表单的操作和接受提交的值的操作)。您在哪里决定要使用哪个用户 ID?你能提供更多的form,以便我们可以看到它是一个表单for

标签: ruby-on-rails ruby


【解决方案1】:

如果您有关联,您可以在 User 上建立关联。

current_user.build_profile(profile_params)

这将自动分配user_id,您无需发送任何隐藏字段。

hidden_field 的问题在于,如果我更改了该字段的值,您的模型或控制器将无法识别。

【讨论】:

  • 嘿@deepak-mahakale,你能在这里详细说明你的代码吗?您是否正在创建一个名为 build_profile 的方法?
  • 您也无法控制用户更改操作 url 中的 id。别再躲在虚假的安全后面了。
  • @coreyward current_user 通常是身份验证的结果,而不是 url 中的 id。在这种情况下,此解决方案似乎是确保仅对当前用户进行修改的理想方法...它与您的 Vote.new(vote_params.merge(user_id: current_user.id)) 方法非常相似,但从用户的角度来看,而不是投票。
  • @BradWerth 这是我的回应,而不是 current_user 的使用:“hidden_​​field 的问题是,如果我更改该字段的值,您的模型或控制器将无法识别。”
【解决方案2】:

假设您的路线如下所示:

resources :users do
  resources :votes
end

...您处理的路径如下所示:

/users/:user_id/votes

...路由到VotesController

如果您向该路径发送 POST 请求,Rails 会将其路由到 VotesController#create 操作。该操作可以通过params 对象访问URL 中传递的user_id 参数,因此您的操作可以执行以下操作:

def create
  @vote = Vote.new(vote_params)
  if @vote.save
    redirect_to user_path(@vote.user_id), notice: :success
  else
    render :new
  end
end

def vote_params
  params.require(:vote).permit(:user_id, :vote_value)
end
protected :vote_params

但是,如果投票不是用户,但仍然是belongs_to用户,您可能有以下路线:

resources :votes

...以及如下所示的路径:

/votes

...路由到您的VotesController。在这种情况下,当您 POST 访问此 url 时,您没有 user_id 参数,但您确实有一个会话对象,该对象具有对代理用户进行身份验证的方式。

在这种情况下,您的控制器方法可能如下所示:

def create
  @vote = Vote.new(vote_params.merge(user_id: current_user.id))
  if @vote.save
    redirect_to some_other_path, notice: :success
  else
    render :new
  end
end

def vote_params
  params.require(:vote).permit(:vote_value)
end
protected :vote_params

【讨论】:

    【解决方案3】:

    你需要给它一个值。您可以在控制器中设置它。

     <%= f.hidden_field :user_id, value: @user.id %>
      or 
     <%= f.hidden_field :user_id, value: params[:user_id] %>
    

    【讨论】:

      【解决方案4】:

      关系模型没有属性user_id,所以不能这样使用:

      <%= f.hidden_field :user_id %>
      

      如果需要提交user_id,试试hidden_​​field_tag,例子:

      <%= hidden_field_tag :user_id, @user.id %>
      

      【讨论】:

        【解决方案5】:

        只是为了补充已经收到的答案,如果您使用 gem 之类的设计,您可以执行以下操作:

        <%= f.hidden_field :user_id, value: current_user.id %>
        

        更多关于如何使用 hidden_​​field 标签的信息here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-08
          • 2012-09-28
          • 2011-08-18
          • 1970-01-01
          • 2017-04-19
          • 1970-01-01
          • 2021-10-11
          • 2016-08-11
          相关资源
          最近更新 更多