Скрытые особенности Ruby on Rails

В качестве компаньона Скрытые черты Ruby.

Попытайтесь сохранить его в Rails, поскольку другой лучше подходит для примеров, специфичных для Ruby. Один за сообщение, пожалуйста.

Ответы

Ответ 1

Чтобы избежать дублирования форм, Rails имеет приятный вариант для отправки тегов:

submit_tag "Submit", :disable_with => "Saving..."

Это добавляет поведение кнопки отправки, чтобы отключить ее после щелчка и отобразить "Сохранение..." вместо "Отправить".

Rails 4 +

 DEPRECATION WARNING: :disable_with option is deprecated and 
 will be removed from Rails 4.1. Use 'data: { disable_with: 'Text' }' instead.

Таким образом, вышесказанное становится следующим:

submit_tag 'Submit', data: { disable_with: 'Text' }

Ответ 2

integer.ordinalize - это один маленький метод, который я просто наткнулся на недолго.

1.ordinalize = "1st"
3.ordinalize = "3rd"

Ответ 3

Я сейчас люблю div_for и content_tag_for

<% div_for(@comment) do %>
  <!-- code to display your comment -->
<% end %>

В приведенном выше коде отображается следующее:

<div id="comment_123" class="comment">
  <!-- code to display your comment -->
</div>

Хотите, чтобы класс CSS был comment other_class? Нет проблем:

<% div_for(@comment, :class => 'other_class') do %>
  <!-- code to display your comment -->
<% end %>

Хотите пролет, а не div? Нет проблем, content_tag_for на помощь!

<% content_tag_for(:span, @comment) do %>
<% end %>

# Becomes...

<span id="comment_123" class="comment">
  <!-- code to display your comment -->
</span>

content_tag_for также отлично подходит, если вы хотите префикс id. Я использую его для загрузки gif.

<% content_tag_for(:span, @comment, 'loading') do %>
  <%= image_tag 'loading.gif' -%>
<% end %>

# Becomes...

<span id="loading_comment_123" class="comment">
  <img src="loading.gif" />
</span>

Ответ 4

Чтобы просмотреть список установленных камней, вы можете запустить:

gem server

Затем укажите браузер:

http://localhost:8808

Вы получаете красиво отформатированный список ваших драгоценных камней со ссылками на rdoc, в Интернете и любых зависимостях. Гораздо приятнее, чем:

gem list

Ответ 5

Вы можете воспользоваться тем фактом, что определения класса Ruby активны и что Rails кэширует классы в рабочей среде, чтобы гарантировать, что постоянные данные извлекаются из базы данных только при запуске приложения.

Например, для модели, представляющей страны, вы должны определить константу, которая выполняет запрос Country.all при загрузке класса:

class Country < ActiveRecord::Base
  COUNTRIES = self.all
  .
  .
  .
end

Вы можете использовать эту константу в шаблоне представления (возможно, в вспомогательном элементе), обратившись к Country::COUNTRIES. Например:

<%= select_tag(:country, options_for_select(Country::COUNTRIES)) %>

Ответ 6

в вашем environment.rb, вы можете определить новые форматы даты/времени, например.

[Time::DATE_FORMATS, Date::DATE_FORMATS].each do |obj|
  obj[:dots] = "%m.%d.%y"
end

то в ваших представлениях вы можете использовать:

Created: <%= @my_object.created_at.to_s(:dots) %>

который будет печататься следующим образом:

Created: 06.21.09

Ответ 7

Если у вас есть модель с некоторыми методами класса и некоторыми областями имен:

class Animal < ActiveRecord::Base
  named_scope 'nocturnal', :conditions => {'nocturnal' => true}
  named_scope 'carnivorous', :conditions => {'vegetarian' => true}

  def self.feed_all_with(food)
    self.all.each do |animal|
      animal.feed_with(food)
    end
  end
end

Затем вы можете вызвать методы класса с помощью именованной области:

if night_time?
  Animal.nocturnal.carnivorous.feed_all_with(bacon)
end

Ответ 8

Rails 2.3.x теперь позволяет:

render @items

намного проще..

Ответ 9

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

render :partial => 'items', :collection => @items

Это вызовет частичный один раз для каждого элемента и каждый раз передает локальную переменную. Вам не нужно беспокоиться о том, что nil проверяет @items.

Ответ 10

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

# models/person.rb
class Person < ActiveRecord::Base

  def after_save
    # do something useful
  end

end


# test/unit/person_test.rb
require 'test_helper'

class PersonTest < ActiveSupport::TestCase

  class ::Person
    def after_save
      # do nothing
    end
  end

  test "something interesting" do
    # ...
  end
end

Ответ 12

Если вы добавили маршрутизацию для ресурса:

ActionController::Routing::Routes.draw do |map|
  map.resources :maps
end

И зарегистрируйте дополнительные типы mime:

Mime::Type.register 'application/vnd.google-earth.kml+xml', :kml

Вам не нужен блок respond_to в вашем контроллере для обслуживания этих дополнительных типов. Вместо этого просто создайте представления для определенных типов, например 'show.kml.builder' или 'index.kml.erb'. Rails будет отображать эти шаблоны для конкретных типов, когда будут получены запросы для '/maps.kml' или '/maps/1.kml', соответствующим образом настроив тип ответа.

Ответ 13

ActionView::Base.default_form_builder = MyFormBuilderClass

Очень полезно, когда вы создаете своих собственных разработчиков форм. Гораздо лучшая альтернатива ручному прохождению: строитель, либо в ваших представлениях, либо в вашем собственном помощнике custom_form_for.

Ответ 14

Возвращаемый блок - отличный способ вернуть значения:

def returns_a_hash(id)
  returning Hash.new do |result|
   result["id"] = id
  end
end

Вернет хэш. Вы также можете заменить любые другие типы.

Ответ 15

Получите все напечатанные с помощью рейк-маршрутов программно:

Rails.application.routes