Ruby on Rails:在创建时分配关系

时间:2015-04-23 21:21:56

标签: ruby-on-rails

我是Ruby on Rails的新手。我的项目有两种模式:房间和客人。该协会是“房间有很多客人”和“客人属于房间”。

我为管理室和客人分开了视图。客房在创建时不需要“客人”价值。但是,我想创建新的客人并同时将其分配到某个房间。什么是正确的方法呢?如何从Web传输输入并匹配数据库中的实体。

代码与"Getting Started with Rails"几乎相同。在教程中,他们在“文章”视图中添加“评论”,并使用“评论”作为“文章”的子资源。在我的情况下,我平等对待这两个模型,并希望在分离的视图中管理它们。

更新

我使用了collection_select并尝试使用我的guest_controller。

<%= form_for :guest, url: guests_path do |f| %>
<% if @guest.errors.any? %>
  <div id="error_explanation">
    <h2>
      <%= pluralize(@guest.errors.count, "error") %> prohibited this guest from being added:
    </h2>
    <ul>
      <% @guest.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

  <p>
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :phone %><br>
    <%= f.text_field :phone %>
  </p>
  <p>
    <%= f.label :room%><br>
    <%= f.text_field :room %>
  </p>
  <p>
  <%= f.label :room %><br>
  <%= f.collection_select(:room_id, Room.all, :id, :title) %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Back', guests_path %>

在我的guest_controller中,上面表单调用的create方法是:

    def create
        @guest = Guest.new(guest_params)
        @guest.room = Room.find(params[:room_id])
        if @guest.save
            redirect_to @guest
        else
            render 'new'
        end
    end

但是,当我创建一个新访客时,它显示:

ActiveRecord::RecordNotFound in GuestsController#create
Couldn't find Room with 'id'=

我检查了room_id = 4,Room.find(4)返回了合适的房间。 怎么了?

2 个答案:

答案 0 :(得分:1)

查看fields_for代码:

http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for

它允许在创建房间并相互关联时创建访客。

答案 1 :(得分:1)

如果您想从存在的房间中选择一个房间,请使用collection_select form helper,以下是文档中的相关摘录:

<head></head>

这会输出一个下拉列表:

  • 在此上下文中填写f.collection_select(:city_id, City.all, :id, :name) 参数
  • 使用city_id填写列表中的选项(我将引用&#34;每个&#34;城市为City.all
  • city用作数据(在表单中发送)
  • 在下拉列表中显示每个城市的city.id(希望是人类可读的)

请记住,就安全而言,它就像&#34;看,你可以选择这个,这个和这个!&#34; ,这不是阻止用户选择不公开的选项:通过手动修改表单标记或发送手工查询。

因此,您是否应限制对特定会议室的访问权限,并仅列出city.nameRoom.unlocked假设范围),确保收到的unlocked指的是该范围内的会议室好。大多数问题都是使用验证或仔细关联管理来处理的(room_id如果房间不在该范围内,则输出Room.unlocked.find_by_id(:room_id)

UPD:至于您遇到的最新问题 - 您对nil中表单内容的外观理解似乎是错误的。这实际上是一种常见的误解。

params将在form_for :guest中构建一个单独的对象/哈希,其中包含所有表单的字段。所以它实际上在params[:guest]内,但不,不要急于添加缺少的部分

您已经从整个params[:guest][:room_id]构建了一个@guest对象,因此如果房间实际存在,它已经在params[:guest]内,并且可以在@guest.room期间的模型。看看Rails validators