遵循DRY原则并尽可能不重复我的代码,从而重用控制器操作和视图。
我在主页上使用了index.html.erb视图,您可以在此处看到http://frnsh.herokuapp.com/
然后重复使用此视图仅显示某个用户/供应商的列表 http://frnsh.herokuapp.com/vendors/2/listings
这很棒,因为我保持DRY并重复使用index.html.erb
但是,当您点击链接并前往http://frnsh.herokuapp.com/vendors/2/listings
时,我想显示该用户/供应商的简历以及最终的他们的徽标这是可能的还是我应该真的创建了vendor.html.erb页面?如果可以保持DRY,我将如何自定义index.html.erb视图?
我的index.html.erb如下:
<div class="center">
<div class="row">
<% @listings.each do |listing| %>
<div class="col-md-3">
<div class="thumbnail">
<%= link_to image_tag(listing.image.url), listing %>
<div class="caption">
<h3><%= listing.name %></h3>
<p><%= link_to listing.user.name, vendor_listings_path(:vendor_id => listing.user.to_param) %></p>
<p><%= number_to_currency(listing.price, :unit => "£") %></p>
<p><%= listing.user.bio %></p>
</div>
</div>
</div>
<% end %>
</div>
</div>
如果需要,我的控制器也在下面:
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, only: [:seller, :new, :create, :edit, :update, :destroy]
before_filter :check_user, only: [:edit, :update, :destroy]
before_filter :set_vendor, only: [:index]
def seller
@listings = Listing.where(user: current_user).order("created_at DESC")
end
def index
@listings = @vendor.present? ? @vendor.listings : Listing.all
@listings = @listings.order("created_at DESC")
end
def show
end
def new
@listing = Listing.new
end
def edit
end
def create
@listing = Listing.new(listing_params)
@listing.user_id = current_user.id
respond_to do |format|
if @listing.save
format.html { redirect_to @listing, notice: 'Listing was successfully created.' }
format.json { render :show, status: :created, location: @listing }
else
format.html { render :new }
format.json { render json: @listing.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @listing.update(listing_params)
format.html { redirect_to @listing, notice: 'Listing was successfully updated.' }
format.json { render :show, status: :ok, location: @listing }
else
format.html { render :edit }
format.json { render json: @listing.errors, status: :unprocessable_entity }
end
end
end
def destroy
@listing.destroy
respond_to do |format|
format.html { redirect_to listings_url, notice: 'Listing was successfully destroyed.' }
format.json { head :no_content }
end
end
答案 0 :(得分:3)
我认为您is it too DRY?
的问题是确实 is it right?
<强>结构强>
我写这个的原因是因为如果你看一下你创建的内容 - 每次调用你想要使用它的相应控制器动作时,你需要调用index
部分。
这很重要,因为当你有一个应用程序时,至少从开发的角度来看,你需要确保你有一个直观的&em;流程。可扩展性。您使用partial运行的 risk 是每次调用时都必须保持相同的结构/接口
虽然不是问题,但每次创建新动作时都会变得非常严格 - 我认为这是您问题的核心方面(当您不知道如何为{{1}添加不同的样式选项时对象)
-
<强>物件强>
我一直在写这么多,但我认为它也适合你 - Rails是object orientated 。这意味着如果你想创建一个部分,你可以更好地适应你通常使用你的控制器/动作视图;将部分应用于特定的对象:
listings
虽然是一个非常简化的演示,但我试图给你的是,如果你break up your partials to display objects,你将能够制作更多modular流< / p>
我认为您当前遇到的问题是您将#app/views/shared/_listing.html.erb #-> partial
<%= link_to listing.name, listing %>
#app/views/application/index.html.erb #-> root path
<%= render "shared/listing", collection: @listings, as: "listing" %>
#app/views/listings/index.html.erb
<%= render "shared/listing", collection: @listings, as: "listing" %>
#app/views/listings/show.html.erb
<%= render "shared/listing", object: @listing %>
视为布局的一部分,因此会遇到一些antipatterns。实际上,您应该使用它来显示特定的对象,然后您可以围绕布局进行定制
答案 1 :(得分:1)
它不太干。实际上,您可以通过将@listings.each
块中的所有内容移动到列表部分然后呈现该部分来进一步干掉它。 Rails提供了一个简写语法,render @listings
将为你循环收集。
根据您的ListingsController
代码,我将假设&#34; /&#34; (主页)URL和&#34; / vendors / 2 / listing&#34; URL既可以路由到列表#index action,也可以显示listing / index.html.erb。这意味着您尝试解决的问题是,如何根据供应商是否通过来显示listing / index.html.erb中的供应商信息。为此,请创建供应商部分,其中包含供应商存在时要显示的供应商信息。然后使用<%= render @vendor %>
渲染供应商。如果缺少@vendor
,render
将返回nil
并且不会显示任何内容,否则将显示部分内容。
Rails指南非常适合有关部分内容的更多信息:http://guides.rubyonrails.org/layouts_and_rendering.html