Обновление атрибутов таблицы соединений в отношении «многие ко многим» - PullRequest
0 голосов
/ 24 августа 2011

У меня есть настройка отношения «многие ко многим» для модели данных, которая имеет дело с проблемной областью «Члены и адреса».Обычно «член» может иметь несколько «адресов», например, когда у вас есть рабочий адрес и домашний адрес.

Я хочу сохранить дополнительные атрибуты в таблице соединений и сохранить данные, кроме атрибутов внешнего ключа.В сети много примеров об отношениях «многие ко многим», но я не нашел подробностей / примеров хранения дополнительных данных.

Вот проблема, с которой я застрял.

Модели настроены следующим образом:

Модели

class Member < ActiveRecord::Base
   has_many :member_addresses
   has_many :addresses, :through => :member_addresses
end

class MemberAddress < ActiveRecord::Base
   belongs_to :address   # foreign key for address -> address_id
   belongs_to :member    # foreign key for member ->member_id
end

class Address < ActiveRecord::Base
   has_many :member_addresses
   has_many :members, :through => :member_addresses

   accepts_nested_attributes_for :members, :allow_destroy => true
end

Accepts_nested_attributes в классе Address предназначен для вложенных форм.

Схема базы данных / Миграции Таблицы (упрощенные для публикации) определены как

create_table "addresses", :force => true do |t|
    t.string  "firstline"
    t.string  "state"
    ....
end

create_table "member", :force => true do |t|
    t.string "name"
    ....
end

create_table "member_addresses", :force => true do |t|
   t.integer "member_id"
   t.integer "address_id"
   t.string  "address_type"
end

Поле 'address_type' в объединяющей таблице предназначено для пометки типа адреса, которыйсвязан с участником (он же «домашний» или «рабочий»)

Обновление этого поля, в котором я застреваю.

Контроллеры и просмотр

Member_controller настраивает модель следующим образом:

members_controller.rb
def new
   @member = Member.new
   @member.addresses.build    #pre-build the associated address
end

Затем представление для страницы участника new actionэто

<% = form_for @member do | m |%>

  <%= m.label :first_name, "First Name"%>
  <%= m.text_field :first_name %>
  </p>

  <%= m.fields_for :addresses do |addrform|%>
    <%= addrform.label :firstline %>
    <%= addrform.text_field :firstline %>
  <% end %>

  <br />
  <%= label_tag 'Type of address' %>
  <%= text_field_tag 'addrtype'    %>
  <br />
  <%= m.submit "Add" %><br />

<% end%>

Идея состоит в том, что с помощью 'accepts_nested_attributes' в модели Member я могу ввести данные в форму длядобавить в имя и адрес атрибуты.Дополнительный label_tag предназначен для публикации данных по типу адреса, который я хочу сохранить

Поэтому, когда форма заполняется данными публикации (формирует ловушку), выглядит так:

{"utf8"=>"✓",
     "authenticity_token"=>"E0R038rcdJmBGjjxQ9nQLHGVbzM4ejA0vsEaIvqkwkE=",
     "member"=>{"first_name"=>"James",
     "last_name"=>"SMith",
     "addresses_attributes"=>{"0"=>{"firstline"=>"this is the first line"}}},
     "addrtype"=>"home",
     "commit"=>"Add"}

Все хорошо - я получаю мои данные Member и данные Address , а также дополнительное поле 'addrtype', которое будет использоваться дляперенося мои дополнительные данные

Теперь, как получить данные в таблицу отношений или объединений?В member_controller создать действие

def create
   # create a member with the params posted 
   @member = Member.new(params[:member])

   # get data for 'relation data'
   @addr_type = params[:addrtype]



  if @member.save!
      #update the relation now created with the address type
      @member.member_addresses.first.address_type = @addr_type

      # save the relationship (is this necessary?)
      @member.save!

      redirect_to members_path
  end

Как вы можете видеть в create Я пытаюсь заполнить данные в таблице соединений и затем принудительно вызватьсохраните снова, чтобы сохранить связь или связь с дополнительным атрибутом.

Это не работает, и / или я делаю это неправильно.

Любые предложения будут наиболее приветствоваться.

Ответы [ 2 ]

1 голос
/ 24 августа 2011

Попробуйте изменить ваши модели на что-то вроде этого:

class Member < ActiveRecord::Base
   has_many :member_addresses
   accepts_nested_attributes_for :member_addresses, :allow_destroy => true
end

class MemberAddress < ActiveRecord::Base
   belongs_to :member    
   has_many :addresses
   accepts_nested_attributes_for :addresses, allow_destroy => true
end

class Address < ActiveRecord::Base
   belongs_to :member_addresses
end

И измените ваш метод member_controller.create на

@member = Member.new(params[:member])

Это должно позволить вам создавать MemberAddresses и Addresses через MemberController.создать метод.

Эти 2 RailsCasts могут также стоить посмотреть

# 196 Вложенная модель, часть формы 1
# 197 Вложенная модель, часть формы 2

0 голосов
/ 24 августа 2011

Не так свободно в Rails, как хотелось бы, однако исследования показывают, что, возможно, это сработает:

Вместо

@member.member_addresses.first.address_type = @addr_type

Попробуйте

@member.member_addresses.create(:address_type => @addr_type)

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