Этот код принадлежит модели или контроллеру - PullRequest
2 голосов
/ 06 февраля 2011

Для начала, я довольно новичок в Rails

Я создал несколько методов и поместил их в свою модель, но это выглядит грязно и просто интересно, принадлежит ли код модели или контроллеру?Что делает мой код уникальным (в любом случае не одна модель на контроллер), так это то, что у меня есть только одна модель "Продукты", но у меня есть 3 контроллера, которые взаимодействуют с ним: "Продавцы, Категории, Бренды".Может быть, есть более простой способ, который я полностью пропустил ??Я действительно не хочу разбивать данные на 3 таблицы / модели со ссылками между ними.

ps Это первый раз, когда я ускользнул от комфорта книги по 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 %>

Ответы [ 3 ]

4 голосов
/ 06 февраля 2011

Таким образом, ваша модель данных, похоже, подходит к тому моменту, когда вы, по крайней мере, захотите разделить торговцев. Вы можете узнать это из запроса «DISTINCT Merchant». Если ваши продавцы основаны на вводе данных пользователем и сохраняются в таблице продуктов, кажется, что сейчас самое время перенести их в свою собственную модель, чтобы их можно было легко находить и контролировать. По мере того, как вы будете получать больше продавцов и больше продуктов, выполнять этот запрос будет все сложнее и сложнее. Как только вы захотите добавить дополнительную информацию о продавце, вы также окажетесь в худшем положении. Просто имейте в виду, что 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 в ваших представлениях.

В общем, вы на правильном пути: тощие контроллеры, представления и толстые модели - это путь. Это означает, что ваша логика и ваш тяжелый подъем в ваших моделях и пусть ваши контроллеры и представления будут маленькими и простыми.

3 голосов
/ 06 февраля 2011

Вероятно, вам следует нормализовать вашу базу данных. Вам нужно 3 таблицы вместо одной: продукты, продавцы и бренды. Ваша таблица продуктов будет содержать ссылки на таблицы продавцов и брендов. После этого у вас могут быть отдельные модели (с отношениями между принадлежащим_сетями / has_many) и отдельными контроллерами.

Вы по-прежнему сможете писать такие вещи, как product.merchant.name, но часть вашего кода будет проще.

2 голосов
/ 06 февраля 2011

Условные обозначения просто обычные.Там нет правильного или неправильного, независимо от того, кто в Атланте говорит вам, что есть.F # $ к нему.

В любом случае, если вы едете с моделью Skinny Controller Fat, то да, вы на правильном пути.

Как говорится, выполняйте всю тяжелую работу в вашей модели.

Я бы хотел провести рефакторинг этих методов лично в модели.Все те места, где вы звоните * .downcase.gsub ...

Также обратите внимание на to_param, метод, который вы можете перезаписать для получения URL-адресов чисток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...