0

这是我的模型的样子。一个用户有很多可以订阅的频道,基于他们的组(User HABTM Group HABTM Channel)以及他们订阅的频道(用户HM频道T订阅,我这里没有使用HABTM,因为订阅会有一个显示顺序列)。

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :subscriptions
  has_many :channels, through: :subscriptions
end

class Group < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_and_belongs_to_many :channels
end

class Channel < ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :subscriptions
  has_many :users, through: :subscriptions
end

class Subscription < ActiveRecord::Base
  belongs_to :user
  belongs_to :channel
end

我所做的是显示用户可以订阅的所有频道的列表(如果有更简单的方法来做到这一点,只需一条 SQL 语句,请告诉我):

@channels = Channel.joins(
  'JOIN channels_groups ON channels.id = channels_groups.channel_id', 
  'JOIN groups_users ON channels_groups.group_id = groups_users.group_id', 
  'JOIN users ON groups_users.user_id = users.id'
).where('users.id = ?', @user.id).uniq

我想不通的是如何围绕这个频道列表创建一种复选框。理想情况下,我希望能够

  1. 如果订阅不存在,则创建用户选中的订阅,
  2. 并删除用户未选中的订阅(如果存在)。

这是嵌套属性形式的东西吗?

4

1 回答 1

0

最终这样做了。觉得可以改进吗?

在我看来:

<% for channel in @channels do %>
  <%= check_box_tag "subscription[][channel_id]", channel.id, @user.channels.include?(channel) %>
  <%= channel.name %>
<% end %>

<%= hidden_field_tag "subscription[][channel_id]", "" %>
<%= submit_tag %>

然后在我的控制器中:

# get all of a users subscriptions that weren't checked and delete them
@user.subscriptions.where('channel_id IN (?)', @user.channel_ids - params[:subscription].map{ |s| s['channel_id'].to_i }.flatten).delete_all
# then add all those that were checked
Subscription.create(params[:subscription]) { |s| s.user_id = @user.id }
于 2013-10-17T18:49:18.793 回答