【问题标题】:Problems using form helpers in ruby on rails在 ruby​​ on rails 中使用表单助手的问题
【发布时间】:2014-11-14 22:10:38
【问题描述】:

我有一个具有以下属性的班级活动:

String type, Date date, String title

通过包含关联,它还具有 user_idplace_id

class Activity < ActiveRecord::Base
   belongs_to :user
   belongs_to :place

在另一边用户有很多活动地方有很多活动

所以,问题是当我想创建一个新活动时: Scaffold 创建助手 _form

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

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

  <div class="field">
    <%= f.label :type %><br>
    <%= f.text_field :type %>
  </div>
  <div class="field">
    <%= f.label :date %><br>
    <%= f.datetime_select :date %>
  </div>
  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :user_id %><br>
    <%= f.number_field :user_id %>
  </div>
  <div class="field">
    <%= f.label :place_id %><br>
    <%= f.number_field :place_id %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

我想从表单中接收前 3 个字段(类型、日期和标题),但要将用户和地点关联起来,我必须以其他方式。我需要实际登录的用户,并且通过提示名称来选择位置。

我的想法如下:

1)用户问题,我可以使用我有权限的current_logged_user查询,获取他的ID。

2)地点问题,我可以使用从表单收到的名称,并在我的 Places 表中查询名称为 X 的地点,然后获取 ID。

但是,由于我对 Rails 了解不多,我该怎么做呢?我如何使用 f.text_field 然后在控制器中进行查询或其他操作?

Controller 已经有了这个东西:

def create
    @activity = Activity.new(activity_params)
(...)

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def activity_params
      params.require(:activity).permit(:type, :date, :title, :user_id, :place_id)
    end

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 form-helpers


    【解决方案1】:

    您可以构建您的 Rails 应用程序,使其既不直接从表单获取 user_id 也不获取 place_id。特别是从提交的表单中获取 user_id 通常不是一个好主意。您通常根本不想将user_id 列入白名单。

    对于 user_id

    如果您使用像 devise 这样的 gem 来进行用户身份验证,它可以让您访问一个名为 current_user 的方法,您可以使用它来设置 user_id。

    对于place_id

    我建议将活动作为地点的子路线。例如不要将表单放在&lt;host&gt;/activities/new 下,而是将其放在 /places/:place_id/activities/new 下。在您的路线文件中将路线如下:

    resources :places do
        resources :activities
    end
    

    现在,在您的控制器操作中,您可以执行以下操作:

    def create
        @activity = current_user.activities.new(activity_params)
        @activity.place_id = params[:place_id] (or even safer will be @activity.place = Place.find(params[:place_id], but this will require one more sql query ) 
        (...)
    private      
    
    # Never trust parameters from the scary internet, only allow the white list through.
    def activity_params
      params.require(:activity).permit(:type, :date, :title)
    end
    

    更新:

    如果您绝对希望在 /activities/new 路线下拥有表单,那么您可以在表单中为 place_id 设置一个选择标签:

    select_tag 'activity[place_id]', options_from_collection_for_select(Place.all, 'id', 'name')
    

    这将创建一个名称为“activity[place_id]”的选择(以 params.require(:activity).permit(place_id) 命名)和看起来像的选项

    <option value="1">Barcelona</option>
    

    【讨论】:

    • 我不理解 /places/:place_id/activities/new 的想法。我要去(并且应该)做的是 /activities/new。感谢您的帮助@AOG
    • 不客气。这个想法是,关联可以在其父 url 下进行,以使 url 提供更多信息,并使后端编码器的生活更轻松。例如。您可以轻松显示“与地点相关的用户活动”之类的内容。
    • 我会看到的。再次感谢您!
    • 我想我明白了。选择我数据库中的所有位置,对吗?
    • 是的,options_from_collection_for_select 的第一个参数是输入 rails 集合,第二个是用于生成值的方法(这里是 id 属性),第三个是方法(这里是 name 属性)用于生成选项文本。 Here 是它的 API 文档。
    猜你喜欢
    • 2010-11-17
    • 1970-01-01
    • 2015-03-03
    • 2011-07-13
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多