我在这里阅读了很多其他主题(1,2,3 ...)但没有一个真正解决了我的问题。
以下是 3 模型。
User
has_many :memberships
has_many :accounts, :through => :memberships
accepts_nested_attributes_for :memberships
end
Account
has_many :memberships
has_many :users, :through => :memberships
accepts_nested_attributes_for :memberships
end
Membership
attr_accessible :account_id, :url, :user_id
belongs_to :account
belongs_to :user
end
如您所见,我的加入模式会员还有一个附加属性::url
。
在我的帐户表中,我存储了在线服务的名称,例如GitHub,Stack Overflow,Twitter,Facebook,LinkedIn ..我总共 9 。这是一个固定数量的帐户,我不经常更新。
在我的用户表单中,我想创建一个:
在任何这些字段中输入的值应仅使用3个值在成员资格表中提交:
url
(在文本字段中输入的值)user_id
(当前用户表单的ID)account_id
(相关帐户的ID,例如LinkedIn为'5')我尝试了3个选项。它们都有效,但只是部分有效。
<% for account in @accounts %>
<%= f.fields_for :memberships do |m| %>
<div class="field">
<%= m.label account.name %><br>
<%= m.text_field :url %>
</div>
<% end %>
<% end %>
我想要 9 文本字段,每个帐户一个。所以我遍历我的帐户,并创建一个与我的会员资格模型相关的网址字段。
首次正确显示我的字段 ,但下次显示 81 字段时
<% @accounts.each do |account| %>
<p>
<%= label_tag(account.name) %><br>
<%= text_field_tag("user[memberships_attributes][][url]") %>
<%= hidden_field_tag("user[memberships_attributes][][account_id]", account.id) %>
<%= hidden_field_tag("user[memberships_attributes][][user_id]", @user.id) %>
</p>
<% end %>
我正在尝试手动在我的会员资格表的每一列中输入3个值。
它有效但是:
<%= f.fields_for :memberships do |m| %>
<div class="field">
<%= m.label m.object.account.name %><br>
<%= m.text_field :url %>
</div>
<% end %>
我正在用户表单中为我的会员模型创建一个嵌套表单。
几乎完美地工作:
但,只有在我的会员资格表已填充后才有效! (例如,使用选项#2)。
所以我尝试使用UsersController构建一些实例:
if (@user.memberships.empty?)
@user.memberships.build
end
但我的m.label m.object.account.name行仍然出现此错误。
undefined method `name' for nil:NilClass
无论如何,我可能在这里错过了一些关于has_many的模型。我已经设法创建了has_and_belongs_to_many关联,但在这里,我想通过第一个模型(User),使用有关第三个模型(Account)的信息来处理该连接模型(Membership)。
我很感激你的帮助。谢谢。
答案 0 :(得分:2)
我会使用以下数据设计方法。系统中的所有用户都应该拥有
所有可能帐户的会员记录条目。活动配置将具有url
字段的值。
User
has_many :memberships
has_many :accounts, :through => :memberships
has_many :active_accounts, :through => :memberships,
:source => :account, :conditions => "memberships.url IS NOT NULL"
accepts_nested_attributes_for :memberships
end
现在
curent_user.active_accounts # will return the accounts with configuration
curent_user.accounts # will return all possible accounts
添加before_filter
以初始化用户可以拥有的所有成员资格。
class UsersController
before_filter :initialize_memberships, :only => [:new, :edit]
private
def initialize_memberships
accounts = if @user.accounts.present?
Account.where("id NOT IN (?)", @user.account_ids)
else
Account.scoped
end
accounts.each do |account|
@user.memberships.build(:account_id => account.id)
end
end
end
在这种情况下,您需要在new
操作之前初始化会员资格,并且所有会员资格都应该
保存在create
操作中(即使是没有url
的操作)。
您的编辑操作无需执行任何其他数据按摩。
注意:强>
我建议使用这种方法,因为它可以直接管理表单/数据。它应该只
如果关联的Account
的数量很少,则使用。
答案 1 :(得分:2)
在控制器中,获取特定用户的成员资格列表
# controller
# no need to make this an instance variable since you're using fields_for in the view
# and we're building additional memberships later
memberships = @user.memberships
然后循环遍历每个帐户并在用户尚未拥有帐户成员资格的情况下构建成员资格。
# still in the controller
Account.find_each do |account|
unless memberships.detect { |m| m.account_id == account.id }
@user.memberships.build account_id: account.id
end
end
然后在你看来,你什么都不做改变:)。