我是铁杆新手。我已经搜索了几天并且已经坚持这个问题了。
我正在建立一个网站,其中有用户,乐队(用户可以加入),旅行(属于乐队)和停止(在旅行中停止)。我有每个表格,以及通过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个)。当我尝试添加游览时,它只是给出了一个错误。我还想尝试使用部分和集合来打破每次项目的渲染。
我的问题是
为什么部分显示相同的名称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
答案 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)
等。