无法在rails 4中显示来自多个嵌套表的数据

时间:2014-01-03 00:27:36

标签: ruby-on-rails ruby-on-rails-4 rails-activerecord nested-attributes partials

我是铁杆新手。我已经搜索了几天并且已经坚持这个问题了。

我正在建立一个网站,其中有用户,乐队(用户可以加入),旅行(属于乐队)和停止(在旅行中停止)。我有每个表格,以及通过id(bandmembership,bandtourmembership,tourstopmembership)将它们链接在一起的其他表格。

我遵循了一些教程并使用了belongs_to,has_many =>通过将这些全部链接在一起,我使用嵌套属性成功地从一个级别深度显示数据。

我想要显示的最终格式是

User Name
=> Band Name #1
====> Tour Name #1
========> Tour Stop #1
========> Tour Stop #2
====> Tour Name #2
========> Tour Stop #1
========> Tour Stop #2
=> Band Name #2
====> Tour Name #3
========> Tour Stop #1
========> Tour Stop #2

目前我只能在没有错误的情况下显示波段名称,但它显示相同的波段名称3次(数据库中有3个)。当我尝试添加游览时,它只是给出了一个错误。我还想尝试使用部分和集合来打破每次项目的渲染。

我的问题是

  1. 为什么部分显示相同的名称3次,如何让它显示正确的名称?

  2. 为什么我无法访问乐队的巡演?如何让它合作?


  3. 视图/用户/ show.html.erb

    <h1>Dashboard</h1>
    <%= render partial: 'shared/user_item' %>
    <% if @user.bands.any? %>
       <h2>You are in <%= @user.bands.count %> bands:</h2>
       <%= render partial: 'shared/band_item', collection: @band_items %>
    <% else %>
    

    共享/ _band_item.html.erb

    <%= @band.name %>
    

    共享/ _tour_item.html.erb

    <%= @tour.name %>
    

    共享/ _stop_item.html.erb

    <%= @stop.name %>
    

    控制器/ users_controller.rb

    class UsersController < ApplicationController
    
      def create
        @user = User.new(user_params)
        if @user.save
          sign_in @user
          flash[:success] = "You are now signed in"
          redirect_to @user
        else
          render 'new'
        end
      end
    
      def show
        @user = User.find(params[:id])
        @band_items = Bandmembership.where(user_id: @user.id)
        @band = Band.find(params[:id])
      end
    
      def new
        @user = User.new
      end
    
      private
    
        def user_params
          params.require(:user).permit(:firstname, :lastname, :email, :password, :password_confirmation)
        end
    
    
    end
    

    模型/ user.rb

    class User < ActiveRecord::Base
    
      has_many :bandmemberships
      has_many :bands, :through => :bandmemberships
      has_many :tours, :through => :bands
    
      accepts_nested_attributes_for :bands, :tours
    
    end
    

    模型/ bandmembership.rb

    class Bandmembership < ActiveRecord::Base
    
      belongs_to :user
      belongs_to :band
    
    end
    

    模型/ tour.rb

    class Tour < ActiveRecord::Base
    
      has_many :tourstopmemberships
      has_many :stops, :through => :tourstopmemberships
    
      has_many :bandtourmemberships
      has_many :bands, :through => :bandtourmemberships
    
      accepts_nested_attributes_for :stops
    
    end
    

1 个答案:

答案 0 :(得分:1)

这闻起来像是通过类级代理方法解决的东西(Rails Antipatterns,pp 6-7)

你有show方法为用户和乐队拉动参数。这是tld.com/user/1/band/3吗?

如果您在ID中没有两者的参数,那么它会拉动用户的带宽ID,反之亦然。

从代码的角度来看,你应该能够重构这样的事情:

<h1>Dashboard</h1>

<%# this should render app/views/users/_user.html.erb %>
<%= render @user %>

<% if @user.bands %>
  <h2>
    You are in <%= @user.bands.count %> bands:
  </h2>
  <ul>
    <%= @user.bands.each do band %>
      <%# this should render app/views/bands/_band.html.erb %>
      <%= render @band,
                 locals: (band: band) %>
    <% end %>
  </ul>
<%- end -%>

你的_band.html.erb将是

<li class="band-name">
    <%= band.name %>
</li>

代码可能不是100%正确,因为我一直在2.3应用程序和4.x应用程序之间跳跃。但原则是:

1。)使用ActiveRecord的功能为您带来好处。你有模型关联,所以你不需要自己进行查找。 @ user.bands应返回用户所属的乐队数组,因为它们属于那些乐队成员。

2。)如果你需要做某事,不要在树上走2到3个项目。例如@ user.band.first.tour.first是坏坏juju。创建一个在User模型上找到它的方法,然后从那里开始,例如

def next_tour
    User.tour.first etc etc
end

然后在视图中将其作为@ user.next_tour或其他任何内容调用。

3.使用render @collection_name的强大功能并使用默认值来清理代码。它比在共享/.// p>中漂浮的许多部分更容易阅读和更好

当我提供我的Rails View会话时,这是我经常使用的东西,部分应该属于它们所在的控制器的文件夹中。 /app/views/tours/_tour.html.erb等等比共享下的tour_item更好。它是应用程序中任何位置的单个游览条目的渲染。

我也不确定将tourtopmemberships作为连接模型。你加入了什么?为什么不只是一个旅游有很多站点和站点属于一个旅游?如果您正在查看场地模型,那么也许停靠是游览和场地之间的连接模型。然后,您可以将其他元数据添加到停止

stop.tour
stop.venue
stop.start_time
stop.support_act (which could be a different relationship)

等。