Rails:隐藏领域的最佳实践

时间:2017-03-14 03:56:22

标签: ruby-on-rails ruby

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

我在提交表单时试图传递user_id,而不是:

<%= f.hidden_field :user_id %> 

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

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

编辑:感谢大家的回复。正如我之前所说的,我知道你不应该使用hidden_​​field来获取像ID这样重要的东西。根据链接@ brad-werth post,这种方式的批量分配太容易了。

我正在添加代码以使其更容易回答。我需要提交下面的表格,并确保将其分配给用户。还有,是的,我正在使用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 %>

5 个答案:

答案 0 :(得分:1)

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

current_user.build_profile(profile_params)

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

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

答案 1 :(得分:0)

假设您的路线看起来像这样:

resources :users do
  resources :votes
end

...你处理的路径如下:

/users/:user_id/votes

...路由到VotesController

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

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到此网址时,您没有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

答案 2 :(得分:-1)

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

<%= f.hidden_field :user_id %>

如果您需要提交user_id,请尝试使用hidden_​​field_tag,例如:

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

答案 3 :(得分:-1)

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

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

答案 4 :(得分:-1)

只是为了添加已经收到的答案,如果您使用的是gem类型的设计,您可以这样做:

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

有关如何使用hidden_​​field标记的详细信息here