2016-10-01 2 views
0

У меня есть три модели: Пользователь, Группа и GroupUserКакова наилучшая практика управления записями в has_many посредством ассоциации?

class User < ActiveRecord::Base 
    has_many :group_users 
    has_many :groups, through: :group_users 

class Group < ActiveRecord::Base 
    has_many :group_users 
    has_many :users, through: :group_users 

class GroupUser < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :user` 

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

Мой вопрос: Каков наилучший способ кодирования после операции отправки (несколько записей добавления/удаления) в контроллер или где-то еще.

Для этого я создал два дополнительных действия в GroupController: def select_users для открытия формы флажка и def add_users для добавления и удаления.

def select_users 
    @group = Group.find(params[:id]) 
    end 

    def add_users 
    @group = Group.find(params[:id]) 
    # Add new users 
    new_users = params[:group][:user_ids] 
    old_users = @group.users.map {|x| x.id.to_s } + [""] 
    add_users = new_users.reject { |item| old_users.include?(item) } 

    add_users.each do |id| 
     @group.users << User.find(id) 
    end 

# Delete unwanted users 
    delete_users = old_users.reject { |item| new_users.include?(item) } 
    @group.group_users.where(user_id: delete_users).destroy_all 

    redirect_to groups_path, notice: 'Users were added.' 

    end` 

Я мог бы создать контроллер GroupUser для присоединиться к столу и положить, что действия, где, как RESTful «новый» и «создать», но я не уверен, что это лучший способ сделать.

+0

Также 'def select_users' довольно сбивает с толку. Если вы собираетесь назвать это, я бы назвал его find_group. При этом не имеет смысла определять его, а затем не использовать в add_users. Если вы хотите определить что-то подобное и использовать его перед действием в вашем контроллере, это было бы нормально, но я не думаю, что это действительно помогает. –

ответ

0

Лучшей практикой является тощий контроллер и толстая модель. Поэтому я бы не поставил эти два метода на ваш контроллер. Контроллер должен в идеале выбрать один модельный метод. Так что я бы изменить это:

def add_users 


@group = Group.find(params[:id]) 
    # Add new users 
    new_users = params[:group][:user_ids] 
    old_users = @group.users.map {|x| x.id.to_s } + [""] 
    add_users = new_users.reject { |item| old_users.include?(item) } 

    add_users.each do |id| 
    @group.users << User.find(id) 
    end 
end 

к чему-то на модели группы

def update_users(user_ids) 
    new_users = User.where(id: user_ids) 
    final_users = new_users + self.users 
    self.users = final_users.uniq 
    self.save 
end 

Насколько успокоительные конвенция я бы поставил это на действие обновления для контроллера групп и использовать accepts_nested_attributes_for вариант.

def update 
    @group = Group.find(params[:id]) 
    if @group.update_users(params[:group][:user_ids]) 
    #handle success 
    else 
    #handle error 
    end 
end 
0

1) Не делайте все это в GroupController - это загромождает его. Создайте новый простой класс ruby ​​для его обработки.

2) Не уверен, но я уверен, вы можете назначить пользователей коллекции, и она будет писать по ассоциации. Таким образом:

@group.users = User.where(id: [1,2,4]) # you can just give it your params[:group][:user_ids] here as the array 
@group.save! # also not sure if this is necessary 
+0

Это еще один допустимый вариант. Лично для поведения в текущей форме я бы не использовал объект поддержки формы. Тем не менее, если группы стали более сложными, я бы использовал PORO (простой старый объект ruby) в качестве объекта поддержки формы. Более подробно об этом см. В этой статье: https://blog.pivotal.io/labs/labs/form-backing-objects-for-fun-and-profit Я бы сказал, учитывая, что воспринимаемый уровень мастерства объектов поддержки формы OP может быть немного продвинутый, но не плохой способ решить эту проблему. –

Смежные вопросы