我是新手。我试图制定涉及商店和糖果,其中一家店可以有很多糖果,一个简单的Web应用程序。
我在我的商店/ show.html.erb下面的代码显示糖果的列表两次。
<% i=0 %>
<% for candy in @shop.candies do %>
<% i+=1 %>
<%= i %> <%= candy.name %>
<% end %>
<%= form_for([@shop, @shop.candies.build]) do |f| %>
<%= render(:partial => 'form',
:locals => {:f => f, :header => "Add a Candy",
:placeholder => "Enter a candy name"}) %>
<% end %>
<% i=0 %>
<% for candy in @shop.candies do %>
<% i+=1 %>
<%= i %> <%= candy.name %>
<% end %>
我在_form.html.erb代码创建一个新的糖果:
<%= f.text_field(:name, :placeholder=> placeholder, :class=>"form-control custom-input")%>
<%= button_tag( :class => "btn btn-primary mb-2 btn-custom btn-custom-sc") do %>
<i class="fas fa-plus icon"></i>
<% end %>
商店控制器的代码:
class ShopsController < ApplicationController
def show
@shop = Shop.find(params[:id])
@unshelved_candies = @shop.candies.unshelved_candies
end
private
def shop_params
params.require(:shop).permit(:name)
end
end
糖果控制器的代码:
class CandiesController < ApplicationController
def create
@shop = Shop.find(params[:shop_id])
@candy = @shop.candies.create(candy_params)
redirect_to(shop_path(@shop))
end
private
def candy_params
params.require(:candy).permit(:name)
end
end
end
当我运行的代码,并查看它在浏览器中,我注意到,它会在第二环(不在数据库中)的空糖果。然而,当我删除的形式创建糖果,它的行为,因为它应该。我无法理解为什么它的循环一次,并显示空值。第一环的输出是正确的:
和第二回路的输出是:
谁能告诉我,为什么它是在第二循环显示空白值,以及如何防止这种额外迭代?
我相信,“额外”糖果是你在这里实例化一个:
<%= form_for([@shop, @shop.candies.build]) do |f| %>
新的糖果糖果名称是零,那么你得到的空白。
顺便说一句,这一点:
<% i=0 %>
<% for candy in @shop.candies do %>
<% i+=1 %>
<%= i %> <%= candy.name %>
<% end %>
令我非惯用的红宝石。我希望看到更多的东西,如:
<% @shop.candies.each.with_index(1) do |candy, index| %>
<%= index %> <%= candy.name %>
<% end %>
我想确保你没有得到额外的糖果会做类似的蛮力方式:
<% @shop.candies.each.with_index(1) do |candy, index| %>
<% unless candy.new_record? %>
<%= index %> <%= candy.name %>
<% end %>
<% end %>
您也可以尝试:
<%= form_for([@shop, @candy]) do |f| %>
我认为可以这样写:
<%= form_for(@shop, @candy) do |f| %>
如果你想保存自己几个按键的(它们加起来一段时间内)。
然后在您的ShopsController
做:
class ShopsController < ApplicationController
def show
@shop = Shop.find(params[:id])
@candy = Candy.new
@unshelved_candies = @shop.candies.unshelved_candies
end
private
def shop_params
params.require(:shop).permit(:name)
end
end
这也是不错的,因为它避免了:
@shop.candies.build
这就要求你view
知道了很多关于shop
和candies
之间的关系,还需要您的view
直接与数据库进行交互。
既然你显然是使用嵌套的路线,你可能想看看shallow: true指令。
同时,(这是不相关的问题),你可能要仔细考虑的Law of Demeter。我注意到你这样做:
@unshelved_candies = @shop.candies.unshelved_candies
就个人而言,我会做更多的东西一样:
@unshelved_candies = @shop.unshelved_candies
而在Shop
,你可能有这样的:
class Shop < ApplicationRecord
def unselved_candies
candies.unshelved
end
end
而在Candy
,是这样的:
class Candy < ApplicationRecord
class < self
def unshelved
where(shelved: false) # or however you determine a candy is unshelved
end
end
end
很多人会做出unshelved
一个scope
,这是做同样的事情的另一种方式。
这样一来,你的ShopsController
知道少谈店和糖果和搁置状态之间的关系的机制。 FWIW。