使用Rails中的选项卡式导航动态渲染部分

时间:2014-09-15 21:34:29

标签: ruby-on-rails twitter-bootstrap render partial

我有一个包含三个模型的网络应用程序 - 客户,工作和客房。它们的关联如下:

class Customer < ActiveRecord::Base
has_many :jobs

class Job < ActiveRecord::Base
belongs_to :customer
has_many :rooms

class Room < ActiveRecord::Base
belongs_to :job

用户可以根据需要创建任意数量的房间。

目前,我的观点如下:

<div class="row">
  <div class="panel panel-primary">
    <div class="panel-heading">
      <h3 class="panel-title center">Room Information</h3>
    </div>
      <div class="panel-body">
        <ul class="nav nav-tabs" role="tablist">
          <% @job.rooms.each do |room| %>
            <li><%= link_to room.room_type %></li>
          <% end %>
        </ul>
            <%= render 'layouts/roomview' %>

            <div class="pull-right">
              <%= link_to new_job_room_path(@job, @customer), class: "btn btn-primary" do %>
                <span class="glyphicon glyphicon-plus"></span>&nbsp;&nbsp;Add New Room
              <% end %>
            </div>
    </div>
  </div>
</div>

在此视图中,我想点击每个标签,然后将房间视图部分渲染为与相应标签相关联的房间。

我的_roomview.html.erb部分内容如下:

<% @job.rooms.each do |job| %>
  <div class="table-responsive">
    <table class="table">
      <tr>
        <h4 class="info-text"><%= room.room_type %> Information</h4>
      </tr>
        <tr class="info">
          <th class="col-md-2 info-text"><u>Room Details</u></th>
          <th class="col-md-2"></th>
          <th class="col-md-2 info-text"><u>Door Style Details</u></th>
          <th class="col-md-2"></th>
          <th class="col-md-2 info-text"><u>Drawer Box Details</u></th>
          <th class="col-md-2"></th>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Room Type:</strong></td>
          <td class="col-md-2"><%= room.room_type %></td>
          <td class="col-md-2"><strong>Upper Door Style:</strong></td>
          <td class="col-md-2"><%= room.upper_door_style %></td>
          <td class="col-md-2"><strong>Drawer Box Style:</strong></td>
          <td class="col-md-2"><%= room.drawer_box_style %></td>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Material Type:</strong></td>
          <td class="col-md-2"><%= room.material %></td>
          <td class="col-md-2"><strong>Lower Door Style:</strong></td>
          <td class="col-md-2"><%= room.lower_door_style %></td>
          <td class="col-md-2"><strong>Drawer Track Style:</strong></td>
          <td class="col-md-2"><%= room.track_style %></td>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Material Details:</strong></td>
          <td class="col-md-2"><%= room.material_details %></td>
          <td class="col-md-2"><strong>Drawer Front Style:</strong></td>
          <td class="col-md-2"><%= room.drawer_front_style %></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Exterior Colour:</strong></td>
          <td class="col-md-2"><%= room.exterior_colour %></td>
          <td class="col-md-2"><strong>Panel Back Style:</strong></td>
          <td class="col-md-2"><%= room.panel_back_style %></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Interior Colour:</strong></td>
          <td class="col-md-2"><%= room.interior_colour %></td>
          <td class="col-md-2"><strong>Finished End Style:</strong></td>
          <td class="col-md-2"><%= room.finished_ends %></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
        </tr>
        <tr class="info">
          <th class="col-md-2 info-text"><u>Counter Top Details</u></th>
          <th class="col-md-2"></th>
          <th class="col-md-2 info-text"><u>Molding Details</u></th>
          <th class="col-md-2"></th>
          <th class="col-md-2 info-text"><u>Custom Order Details</u></th>
          <th class="col-md-2"></th>
        </tr>       
        <tr>
          <td class="col-md-2"><strong>Counter Top Material:</strong></td>
          <td class="col-md-2"><%= room.counter_top_material %></td>
          <td class="col-md-2"><strong>Closed To Ceiling:</strong></td>
          <td class="col-md-2"><%= room.closed_to_ceiling %></td>
          <td class="col-md-2"><strong>Custom Order Name:</strong></td>
          <td class="col-md-2"><%= room.order_name %></td>
        </tr>   
        <tr>
          <td class="col-md-2"><strong>Counter Top Supplier:</strong></td>
          <td class="col-md-2"><%= room.counter_top_supplier %></td>
          <td class="col-md-2"><strong>Crown Molding:</strong></td>
          <td class="col-md-2"><%= room.crown_molding %></td>
          <td class="col-md-2"><strong>Custom Order Details:</strong></td>
          <td class="col-md-2"><%= room.order_description %></td>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Counter Top Colour:</strong></td>
          <td class="col-md-2"><%= room.counter_top_colour %></td>
          <td class="col-md-2"><strong>Under Cabinet Molding:</strong></td>
          <td class="col-md-2"><%= room.under_cabinet_molding %></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Counter Top Edge:</strong></td>
          <td class="col-md-2"><%= room.counter_top_edge %></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Counter Top Backsplash:</strong></td>
          <td class="col-md-2"><%= room.backsplash %></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
        </tr>
        <tr>
          <td class="col-md-2"><strong>Sink Install:</strong></td>
          <td class="col-md-2"><%= room.sink_install %></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
          <td class="col-md-2"></td>
        </tr>

    </table>
  </div>
<% end %>

以下是我的路线:

resources :customers do
  resources :jobs
end

resources :jobs do
  resources :rooms
end

最后,这是我的工作展示控制器:

def show
  @job = Job.find(params[:id])
  @customer = Customer.find(params[:customer_id])
end

现在看来,当我加载视图时,我收到show action的控制器名称错误。该错误表明我有一个未定义的方法用于&#39; room&#39;。

考虑到我上面说明的功能 - 有人可以排除故障吗?我不确定如何构建show动作以正确渲染我的部分。


这是确切的错误字符串:

undefined local variable or method `room' for #<#<Class:0x007fa01f9827b0>:0x007fa01f9a8d48>

1 个答案:

答案 0 :(得分:3)

这里有几个问题:


<强>控制器

如果您的模型是嵌套,为什么不在控制器调用中使用您的关联:

#app/controllers/jobs_controller.rb
class JobsController < ActiveRecord::Base
  def show
    @customer = Customer.find params[:customer_id]
    @job = @customer.jobs.find params[:id]
  end
end

效率更高!


错误

您的错误非常明确:

undefined local variable or method `room'

这意味着在show视图中的某个位置,您的应用会尝试引用room(本地var),而不会对其进行定义。如果没有具体提到相关错误,我将不得不解决问题的原因:

#app/views/jobs/_roomview.html.erb
<% @job.rooms ...

首先,以上是不正确的。在部分内容中,您需要通过"local" variables(否则,他们将失去modularity):

<%= render partial: "roomview", locals: { job: @job } %>

使用以下内容会更好:

<%= render partial: "roomview", collection: @job.rooms, as: :room %>

#_roomview.html.erb
(no need for .each any more)
<div class="table-responsive"> ....

-

最后,我会看一下你如何调用show视图的各种依赖关系。特别是partial,还有links等。您有以下链接:

<%= link_to room.room_type %>

当然你最好打电话给<%= link_to "Room", room.room_type %>