Для этого есть веская причина. Когда вы создаете ассоциацию типа has_many :departments
, rails создает несколько методов для вас, включая departments
, departments=
и так далее.
Теперь давайте рассмотрим случай nested_attributes. Я не знаю, знали ли вы об этом, но параметры, которые вы передаете в хэш params, не ограничиваются только атрибутами. Они будут работать для любого метода. Возьмите этот пример:
class Company < ActiveRecord::Base
def iliketurtles= attrs
attrs.split(/\s+/).each{|attr| self.send "#{attr}=", 'turtles'}
end
def iliketurtles
self.attributes.select{|attr, value| value == 'turtles'}.join(' ')
end
end
В этом примере любые атрибуты модели, которые я передаю iliketurtles=
(в виде строки, разделенной пробелами), устанавливают значения этих атрибутов как "черепахи". А вызов «Iliketurtles» даст вам строку атрибутов, разделенных пробелами, значение которых равно черепахам. Вот интересная часть. Теперь я могу включить iliketurtles
в мои формы:
<%= f.text_field :iliketurtles %>
или параметры напрямую:
params[:company] = {
:name => 'Foo Inc',
:iliketurtles => 'description type address'
}
Итак, что делает nested_attributes, так это создает еще два метода, departments_attributes
и departments_attributes=
, в основном "accessors" или "setters and getters". Итак, есть методы, созданные для обработки вложенных атрибутов. Проблема в том, что вы не можете назвать эти методы доступа departments
и departments=
, потому что эти имена методов уже приняты ассоциацией.
Есть ли лучший способ сделать это? Возможно, но это потребует фундаментальных изменений в способе, которым rails преобразует параметры в атрибуты, и может ограничить возможности разработчиков. Возможность использовать пользовательские средства доступа гораздо мощнее, чем мой пример с черепахой, и это заставит вас поверить:)