Ruby on rails 如何优雅地处理Rails翻译的双边关系?
我有一个Ruby on rails 如何优雅地处理Rails翻译的双边关系?,ruby-on-rails,activerecord,ruby-on-rails-4,Ruby On Rails,Activerecord,Ruby On Rails 4,我有一个家庭树,有人可以将他们的亲戚添加到该树中 因此,所发生的是为每个家族树条目创建了一个成员资格记录 但是,如果一个儿子添加了一个父亲,我们应该能够更新父亲的家谱,将“儿子”添加到视图中的树中。Rails实现这一点的最佳方式是什么?我知道Rails做了很多本机翻译和多元化等工作。不管怎样,我要利用这些来做我想做的事情吗 另外,处理这些东西的类/模块是什么?主动支持 这是我的用户型号: # == Schema Information # # Table name: users # # id
家庭树
,有人可以将他们的亲戚添加到该树中
因此,所发生的是为每个家族树条目创建了一个成员资格记录
但是,如果一个儿子
添加了一个父亲
,我们应该能够更新父亲的家谱,将“儿子”添加到视图中的树中。Rails实现这一点的最佳方式是什么?我知道Rails做了很多本机翻译和多元化等工作。不管怎样,我要利用这些来做我想做的事情吗
另外,处理这些东西的类/模块是什么?主动支持
这是我的用户
型号:
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# email :string(255) default(""), not null
# encrypted_password :string(255) default(""), not null
# reset_password_token :string(255)
# reset_password_sent_at :datetime
# remember_created_at :datetime
# sign_in_count :integer default(0), not null
# current_sign_in_at :datetime
# last_sign_in_at :datetime
# current_sign_in_ip :string(255)
# last_sign_in_ip :string(255)
# created_at :datetime
# updated_at :datetime
# name :string(255)
# confirmation_token :string(255)
# confirmed_at :datetime
# confirmation_sent_at :datetime
# unconfirmed_email :string(255)
# invitation_relation :string(255)
# avatar :string(255)
#
class User < ActiveRecord::Base
has_one :family_tree, dependent: :destroy
has_many :memberships, dependent: :destroy
has_many :nodes, dependent: :destroy
has_many :participants, dependent: :destroy
end
Membership.rb
:
# == Schema Information
#
# Table name: memberships
#
# id :integer not null, primary key
# family_tree_id :integer
# user_id :integer
# created_at :datetime
# updated_at :datetime
# relation :string(255)
#
class Membership < ActiveRecord::Base
belongs_to :family_tree
belongs_to :user
end
我的\u tree.html.erb
如下所示(为简洁起见被截断):
-
“img圆”),族树路径(membership.user.family树),:target=>“\u blank”%>
“\u空白“%”
尚未添加任何内容,请添加“邀请朋友”%>
-
“img圆”),族树路径(membership.user.family树),:target=>“\u blank”%>
“\u空白“%”
尚未添加任何内容,请添加“邀请朋友”%>
我将使用您在问题中定义的相同关系,但本部分除外:
class Membership < ActiveRecord::Base
belongs_to :family_tree
belongs_to :user_one, class_name: 'User'
belongs_to :user_two, class_name: 'User' # I actually have no idea how to call them!
belongs_to :relation # to hold values likes 'Son', 'Dad', etc.
# The model Relation would be as simple as a name and internal reference, nothing else.
# (internal_reference is here to solve the translation problems and other stuff you will understand with the following code)
英语不是我的母语,这段代码可能缺乏一致性(连贯性、逻辑性)
希望这有帮助 请删除所有不相关的代码(Desive、attr_accessible、Carrierwave、其他关联等);明确新的家庭关系是如何创建的(邀请令牌的作用是什么?)。此外,如果可能和适当,将低级细节抽象为邀请令牌。最后一件事:你提到了翻译。什么意思?Rails改变关联名称的能力?你想知道如何在视图中自动生成字符串吗?@tompave我清理了它。当我说翻译时,是的,我最初想到的是屈折变化。从本质上说,应用程序可以根据当前用户的性别自动知道关系的另一面是什么。如果我是男性,那么对我叔叔来说,我永远是侄子。如果我是女性,我将永远是侄女。同样,如果我是男性,我将是祖父母的孙子和父母的儿子。这就是我的意思。在上阅读树实现背后的理论。嵌套集可以在一个查询中构造整个树。它使得跨级别的遍历变得微不足道。树的构造和导航也是一个需要解决的问题。如果您构建一个定制的解决方案,您将花费您的青春努力使其满足您当前和未来的需求:-)内部参考来自哪里?这是Rails方法吗?如果是这样的话,有链接到它吗?它不是Rails方法,而是由您(应用程序管理员)存储在DB、controller中的值。因此,您可以使用相同的关系,使用内部_引用,并根据需要将其翻译成多种语言。此外,它也不完全依赖于单词,而不是做dad=Relation.where(name:'dad')。首先,你使用内部参照,即使是“dad”、“Father”、“Papa”(法语)等,也总是相同的。那么relationship\u name
是从哪里来的呢?或者你的意思是“关系.名称”
?i、 e.self.relation.name
其中self
是Membership
类的一个实例?另外,这种方式是否意味着当我创建关系模型时,我必须为每个关系类型预先填充一组记录?i、 e.儿子、女儿、父亲、母亲、祖父等
?对此有进一步的想法吗?见我前面的问题。还在吗?很抱歉@marcamillion我没有看到你之前的评论relationship\u name
是一个错误,我将其替换为relationship.internal\u reference
,其中relationship
是relationship类的一个实例。是的,这意味着您必须用您命名的关系预先填充DB。(冻结的_记录gem可以帮助您处理此案例)
# == Schema Information
#
# Table name: nodes
#
# id :integer not null, primary key
# name :string(255)
# family_tree_id :integer
# user_id :integer
# media_id :integer
# media_type :string(255)
# created_at :datetime
# updated_at :datetime
# circa :datetime
# is_comment :boolean
#
class Node < ActiveRecord::Base
belongs_to :family_tree
belongs_to :user
belongs_to :media, polymorphic: true, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :node_comments, dependent: :destroy
end
<li class="tree-item-name"><a href="#">Great Grandparents</a>
<ul>
<li><% if relative.humanize == "Great Grandfather" || relative.humanize == "Great Grandmother" %>
<%= link_to image_tag(membership.user.avatar.url, size: "48x48", :class => "img-circle") , family_tree_path(membership.user.family_tree), :target => '_blank' %>
<%= link_to membership.user.name, family_tree_path(membership.user.family_tree), :target => '_blank'%>
<% else %>
None added yet, add them <%= link_to 'here', "#" , class: 'btn invite popupbox','data-popup' => 'invite_friend' %>
<% end %>
</li>
</ul>
</li>
<li class="tree-item-name"><a href="#">Grandparents</a>
<ul>
<li><% if relative.humanize == "Grandfather" || relative.humanize == "Grandmother" %>
<%= link_to image_tag(membership.user.avatar.url, size: "48x48", :class => "img-circle") , family_tree_path(membership.user.family_tree), :target => '_blank' %>
<%= link_to membership.user.name, family_tree_path(membership.user.family_tree), :target => '_blank' %>
<% else %>
None added yet, add them <%= link_to 'here', "#" , class: 'btn invite popupbox','data-popup' => 'invite_friend' %>
<% end %>
</li>
</ul>
</li>
class Membership < ActiveRecord::Base
belongs_to :family_tree
belongs_to :user_one, class_name: 'User'
belongs_to :user_two, class_name: 'User' # I actually have no idea how to call them!
belongs_to :relation # to hold values likes 'Son', 'Dad', etc.
# The model Relation would be as simple as a name and internal reference, nothing else.
# (internal_reference is here to solve the translation problems and other stuff you will understand with the following code)
def create_reverse_membership
user_one_is_female = user_one.gender == 'female'
user_two_is_female = user_two.gender == 'female'
son_or_daughter = user_one_is_female ? :daughter : :son
father_or_mother = user_two_is_female ? :mother : :father
case relation.internal_reference.to_sym
when :son
relation = Relation.find_by_internal_reference(father_or_mother)
membership = Membership.where(relation_id: relation.id, user_one: user_two.id, user_two: user_one.id).first
if membership.present?
# This means the reverse membership already exists, do not call Membership.create here because it would cause and endless loop with the callback
else
membership = Membership.create(relation_id: relation.id, user_one: user_two, user_two: user_one)
end
when :father
# almost same logic but with `son_or_daughter`
when :mother
else
end
end