У нас есть следующий код, работающий для сложной формы рельсов с флажками.Я не очень доволен решением, которое у нас есть, и мне было интересно, если кто-нибудь знает о более правильном способе сделать это в рельсах.Весь код ниже работает, я просто хочу знать, есть ли более чистый подход.
В моем контроллере Admins я хочу убрать необходимость вызывать следующий код при каждом обновлении.
@user.admin.school_admin_roles.destroy_all
params[:roles].each do |school_role|
ids = school_role.split('_')
@user.admin.school_admin_roles.find_or_create_by_school_id_and_school_role_id(ids[0], ids[1])
end if !params[:roles].nil?
Так что я в основном хочу иметь возможность вызывать @ user.update_attributes (params [: user]) и поручить рельсам создавать необходимые мне отношения.У меня есть что работает с AccountRole в форме ниже.Я хочу знать, есть ли способ сделать то же самое с SchoolRole, если у меня есть дополнительная переменная school_id в таблице соединений.
У нас есть следующая форма для редактирования пользователя и назначения ролей
Снимок экрана формы -> http://i.stack.imgur.com/PJwbf.png
У меня есть следующая форма, где администратор может редактировать других пользователей и назначать роли на основе учетной записи и роли на основе школы с помощью флажков.Роли на основе учетных записей было легко реализовать.Правила, основанные на школе, немного сложны, так как объединяющая таблица school_admin_roles имеет поля school_id, user_id, role_id.Мы должны были реализовать школьные роли частью формы довольно хакерским способом.У нас есть форма, реализованная следующим образом: обратите внимание, как мы взломали school.id.to_s + '_' + role.id.to_s в один и тот же флажок для школьных ролей.
В функции обновления контроллера Admins мы вручную уничтожаемвсе роли school_admin в каждом обновлении затем циклически перебирают параметры школьных ролей по идентификаторам на «-», а затем вручную воссоздают каждую школьную роль.Я действительно ненавижу способ, которым мы должны были пойти по этому поводу.Может ли кто-нибудь пролить свет на более чистый, более рельсовый подход к решению этого сценария?
Форма -
<%= form_for @user, :url => {:controller => 'admins', :action => 'update'} do |f| %>
<%= f.label :username %>
<%= f.text_field :username %>
<%= f.fields_for :admin do |uf| %>
<div class="field">
<%= uf.label :first_name %>
<%= uf.text_field :first_name %>
</div>
<label>Admin Permissions</label>
#account level permissions works fine
<%= hidden_field_tag "#{uf.object_name}[account_role_ids][]" %>
<% AccountRole.find(:all).each do |role| %>
<div class="account_role">
<%= check_box_tag "#{uf.object_name}[account_role_ids][]", role.id, @user.admin.account_roles.include?(role)%>
<%= role.name %>
</div>
<% end %>
#school level permissions a bit of a hack
<%= hidden_field_tag "#{uf.object_name}[school_role_ids][]" %>
<% SchoolRole.find(:all).each_with_index do |role, index| %>
<div class="school_role">
<%= check_box_tag "#{uf.object_name}[school_role_ids][]",role.id, @user.admin.school_roles.include?(role) %>
<%= role.name %>
<span class="advanced_box admin_permissions" <% if @user.admin.school_roles.include?(role) %>style="display:inline"<% end %>>
<div class="content" id="perm_<%= index %>">
<h4><%= role.name %></h4>
<% uf.object.account.schools.each do |school|%>
<div>
<%= check_box_tag "roles[]", school.id.to_s+'_'+role.id.to_s, role.school_admin_roles.where(:admin_id => uf.object.id).collect(&:school_id).include?(school.id)%>
<%= school.name %>
</div>
<% end %>
<%= link_to 'Done', '#', :class => "done" %>
</div>
<a href="#" class="open"> Advanced</a>
</span>
</div>
<% end %>
</div>
<% end %>
Контроллер
class AdminsController < ApplicationController
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
# TODO find a way to refactor this
@user.admin.school_admin_roles.destroy_all
params[:roles].each do |school_role|
ids = school_role.split('_')
@user.admin.school_admin_roles.find_or_create_by_school_id_and_school_role_id(ids[0], ids[1])
end if !params[:roles].nil?
#
flash[:notice] = "Successfully updated Admin."
redirect_to admins_path
else
render "edit"
end
end
end
Учитывая следующие модели
class User < ActiveRecord::Base
has_one :parent
has_one :admin
has_many :scool_admin_roles
has_many :account_admin_roles
end
class AccountAdminRole < ActiveRecord::Base
before_save :set_account_id
belongs_to :admin
belongs_to :account_role
end
class SchoolAdminRole < ActiveRecord::Base
belongs_to :admin
belongs_to :school_role
belongs_to :school
end
class SchoolRole < ActiveRecord::Base
has_many :school_admin_roles
end
class AccountRole < ActiveRecord::Base
has_many :account_admin_role
end