Rails 3 вложенных атрибута?
Я новичок в рельсах, так что на этом мне не хватает... Короче, у меня есть приложение, которое отслеживает сервисы (серверы) с IP-адресами. Я пытаюсь настроить его так, чтобы при создании новой службы происходило следующее:
- Все IP-адреса просматриваются, если у них нет service_id, они классифицируются как доступные и возвращаются в поле выбора на новой странице сервиса.
- Пользователь выбирает один или несколько IP-адресов из поля выбора, заполняет остальные необходимые данные службы, а затем, когда они нажимают "Отправить", каждый IP-адрес обновляется с помощью service_id только что созданной службы. (так что IP помечается как занятый).
Как я понимаю, я думаю, что это должно быть возможно либо с вложенными атрибутами, либо с виртуальными атрибутами... Но я не уверен.
У меня есть такие модели:
class Service < ActiveRecord::Base
has_many :ips
attr_accessor :service_ips
end
class Ip < ActiveRecord::Base
belongs_to :service
end
Контроллер вроде так:
class ServicesController < ApplicationController
def new
@available_ips = Ip.where(:service_id == nil)
end
И такой вид:
<%= form_for(@service) do |f| %>
<%= f.label :service_ips %>
<%= f.collection_select(:service_ips, @available_ips, :id, :address, { }, {:multiple => true, :size => 5}) %>
<%= f.label :hostname %><br />
<%= f.text_field :hostname, :size => 40 %>
<%= f.submit :id => "submit"%>
<% end %>
Как сделать так, чтобы каждый выбранный IP-адрес обновлялся только что созданным service_id?
Заранее спасибо за помощь.
1 ответ
На самом деле это не вложенные атрибуты, и вам не нужны виртуальные атрибуты. Вы просто редактируете отношения "есть много".
Во-первых, вы, вероятно, хотите использовать действия edit/update для RESTful. Прочитайте руководство по маршрутизации.
В ваших маршрутах.rb:
resources :services
Затем:
class ServicesController
def edit
@service = Service.find(params[:id])
@available_ips = Ip.where(:service_id => nil)
end
def update
@service = Service.find(params[:id])
if @service.update_attributes params[:service]
redirect_to @service
else
render :edit
end
end
end
Вам не нужен аксессор в вашей модели, коллекция является аксессором:
class Service < ActiveRecord::Base
has_many :ips
end
class Ip < ActiveRecord::Base
belongs_to :service
end
Тогда в ваших views/services/edit.html.erb:
<%= form_for(@service) do |f| %>
<%= f.label :ips %>
<%= f.collection_select(:ip_ids, @available_ips + @service.ips, :id, :address, { }, {:multiple => true, :size => 5}) %>
<%= f.label :hostname %><br />
<%= f.text_field :hostname, :size => 40 %>
<%= f.submit :id => "submit" %>
<% end %>