首先,我是Rails的新手
我已经创建了一些方法并将它们放入我的模型中,但它看起来很乱,只是想知道代码是属于模型还是控制器?是什么让我的代码独一无二(每个控制器无论如何不是一个模型)是我只有一个模型“产品”,但有3个与之交互的控制器,“商家,类别,品牌”。也许有一种我更容易被忽略的方式?我真的不想将数据分成3个表/模型,其中包含链接。
P.S。这是我第一次从舒适的Rails书中溜走,所以请放轻松我吧!对我的代码的任何其他一般性建议将不胜感激。
产品型号
class Product < ActiveRecord::Base
validates :brand, :presence => true
def product_name
name.capitalize.html_safe
end
def product_description
description.html_safe
end
#Replace '-' with ' ' for nice names
def brand_name
brand.capitalize.gsub('-',' ')
end
def category_name
category.capitalize.gsub('-',' ')
end
def merchant_name
merchant.capitalize.gsub('-',' ')
end
#Replace ' ' with '-' for urls
def brand_url
brand.downcase.gsub(' ','-')
end
def category_url
category.downcase.gsub(' ','-')
end
def merchant_url
merchant.downcase.gsub(' ','-')
end
end
商家控制器
class MerchantsController < ApplicationController
def index
@merchants = Product.find(:all, :select => 'DISTINCT merchant')
end
def show
@products = Product.find(:all, :conditions => ['merchant = ?', params[:merchant]])
@merchant = params[:merchant].capitalize.gsub('-',' ')
end
end
商家视图(索引)
<h1>Merchant list</h1>
<%= @merchants.count%> merchants found
<% @merchants.each do |merchant| %>
<p><%= link_to merchant.merchant_name, merchant.merchant_url %></p>
<% end %>
商家视图(显示)
<h1>Products from merchant: <%= @merchant %></h1>
<%= @products.count%> products found
<% @products.each do |product| %>
<h3><%= product.product_name %></h3>
<p>
<img src="<%= product.image %>" align="right" alt="<%= product.product_name %>" />
<%= product.product_description %>
</p>
<p><%= product.price %></p>
<p>Brand: <%= product.brand_name %></p>
<p>Category: <%= product.category_name %></p>
<p>Sub category: <%= product.sub_category %></p>
<p>Merchant: <%= product.merchant_name %></p>
<p><a href="<%= product.link %>" target="_blank">More information</a></p>
<hr />
<% end %>
答案 0 :(得分:4)
因此,您的数据模型确实似乎已经达到了您可能至少想要拆分商家的程度。您可以从选择的“DISTINCT商家”查询中进行说明。如果您的商家是基于用户的输入并保存在您的产品表中,那么现在似乎是将它们移动到自己的模型中的好时机,以便它们易于搜索和管理。随着您获得更多商家和更多产品,执行此查询将变得越来越难。一旦您想要添加其他商家信息,您也会处于更糟糕的位置。请记住,Rails是为了轻松重构而制作的。进行此更改不应该令人生畏,它应该只是敏捷开发过程中的另一项常规任务。
上述更改还允许您更改这些行:
@products = Product.find(:all, :conditions => ['merchant = ?', params[:merchant]]) @merchant = params[:merchant].capitalize.gsub('-',' ')
成:
@merchant = Merchant.find_by_name(params[:name]) @products = @merchant.products
然后,您可以使用模型函数的大写和gsub名称:
@merchant.display_name
下一步是稍微干掉你的模型代码,例如:
class Product def brand_name make_name brand end def category_name make_name category end def merchant_name make_name merchant end private def make_name name name.capitalize.gsub('-', ' ') end end
您也可以执行与_url函数类似的操作。如果你想进一步冒险,你也可以使用元编程来清理它。
最后的想法:确保你真的想要在你的字符串上调用html_safe。如果它们是基于用户的输入,则最好让它们通过视图中的h函数。您是否希望用户能够输入HTML字符串作为品牌,商家和类别?如果是这样,那么将html_safe字符串保留在那里,否则在你的视图中将字符串设为html_safe。
一般来说,你是在正确的道路上:Skinny Controllers and Views和Fat Models是要走的路。这意味着将您的逻辑和繁重工作放入模型中,让控制器和视图变得小而简单。
答案 1 :(得分:3)
您应该规范化数据库。您需要3个表而不是1个:产品,商家和品牌。然后,您的产品表将引用商家和品牌表。然后,您可以拥有单独的模型(它们之间具有belongs_to / has_many关系)和单独的控制器。
您仍然可以编写product.merchant.name
之类的内容,但有些代码会更简单。
答案 2 :(得分:2)
惯例就是常规。无论亚特兰大有谁告诉你,有没有对错。 F#$ k他。
无论如何,如果你要使用Skinny Controller Fat模型,那么,你是在正确的轨道上。
正如他们所说,做你模型中所有繁重的工作。
我希望在模型中亲自重构这些方法。所有你打电话的地方* .downcase.gsub ......
另请查看to_param
,这是一种可以覆盖以获取纯净网址的方法。