Rails: метод Create доступен во всех видах и во всех моделях - PullRequest
4 голосов
/ 18 марта 2010

Я бы хотел определить метод, который доступен как для моих представлений , так и для моих моделей

Скажем, у меня есть помощник вида:

def foo(s)
  "hello #{s}"
end

Представление может использовать помощника следующим образом:

<div class="data"><%= foo(@user.name) %></div>

Однако этот <div> будет обновляться повторяющимся вызовом AJAX.Я использую вызов to_json в контроллере, который возвращает данные следующим образом:

render :text => @item.to_json(:only => [...], :methods => [:foo])

Это означает, что мне необходимо определить foo в моей модели Item:

class Item
  def foo
    "hello #{name}"
  end
end

Было бы неплохо, если бы у меня был DRY метод, которым можно было бы поделиться в и моих представлениях и моих моделях.

Использование можетвыглядят так:

Помощник

def say_hello(s)
  "hello #{s}"
end

Модель User.rb

def foo
  say_hello(name)
end

Модель Item.rb

def foo
  say_hello(label)
end

Просмотр

<div class="data"><%= item.foo %></div>

Контроллер

def observe
  @items = item.find(...)
  render :text => @items.to_json(:only=>[...], :methods=>[:foo])
end

Я не знаю лучший способ справиться с этим, но я не хочу полностью идти против лучших практик здесь.

Еслиты можешь придумать лучший способ, я очень хочу учиться!

Ответы [ 2 ]

5 голосов
/ 20 марта 2010

Вы можете добавить несколько модулей, а затем добавить в модели, чтобы метод работал (для определенного атрибута), примерно так:

Модули (добавьте это в папку lib)

module hasFoo
  def self.included(base)
    base.extend ClassMethods
  end
end

module ClassMethods
  def has_foo(method)
     define_method foo do
       field = self.send(method.to_sym)
       field
     end
  end
end

Тогда в вашей модели просто добавьте

has_foo :name

Тогда вы можете просто позвонить model.foo

И я думаю, что это сделало бы ...

1 голос
/ 18 марта 2010

Я бы просто поместил этот метод в мою модель, которая доступна как для просмотра, так и для контроллера.

Модель:

def say_hello
  "hello #{self.name}"
end

Чтобы добавить это ко всем вашим моделям:

class AbstractModel < ActiveRecord::Base  
  self.abstract_class = true

   def say_hello
      self.respond_to?(:name) ? "hello #{self.name}" : "hello" 
   end

end

class MyModel < AbstractModel
end

Тернарный оператор на response_to? обрабатывает случай, когда модель не имеет имени столбца.

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