【问题标题】:Rails controllers architecture with many to many relationships and modal dialogs具有多对多关系和模式对话框的 Rails 控制器架构
【发布时间】:2015-08-13 01:37:19
【问题描述】:

我正在通过 RubyOnRails 开发一个门户网站,学生、老师和家长可以在该门户网站上使用他们的艺术作品参加不同的比赛。

有 3 个实体:ContestsCategories(竞争对手类别/年龄组)和Nominations(活动种类)。 Contest 可以有多个 Categories。每个ContestCategory 可以有多个Nominations。每个Category 可以属于多个Contests。每个Nomination 可以属于多个ContestCategories。所以我假设ContestsCategories之间存在多对多关系,ContestCategoriesNominations之间存在多对多关系。我创建了以下模型:Contest (contest.rb)、Category (category.rb)、Nomination (nomination.rb)、ContestCategory (contest_category.rb) 和 ContestCategoryNomination (contest_category_nomination.rb) )。

我的模型:

class Category < ActiveRecord::Base
  has_many :contest_categories
  has_many :contests, through: :contest_categories
end

class Contest < ActiveRecord::Base
  has_many :contest_categories
  has_many :categories, through: :contest_categories
  has_many :nominations, through: :contest_categories
  has_one :provision
end

class ContestCategory < ActiveRecord::Base
  belongs_to :contest
  belongs_to :category
  has_many :contest_category_nominations
  has_many :nominations, through: :contest_category_nominations
end

class ContestCategoryNomination < ActiveRecord::Base
  belongs_to :contest_category
  belongs_to :nomination
end

class Nomination < ActiveRecord::Base
  has_many :contest_category_nominations
  has_many :contest_categories, through: :contest_category_nominations
  has_many :contests, through: :contest_categories
end

我想在创建新的Contest 期间创建一个基于 ajax 的模式窗口,以将其与Category 链接并选择多个属于此CategoryNominations

  1. 我应该创建什么控制器来满足 has_many 关系 我的模型之间?
  2. rails 中有哪些命名约定(单数和复数)以满足我的需求 关系?例如,ContestsCategoriesControllerContestCategoryNominationsController 或者可能是 ContestCategoryNominationsController?
  3. 我应该在这个控制器中创建什么动作方法来调用 渲染这个模态窗口?应该是new_category 行动 CategoriesControllernew ContestsCategoriesController 中的操作 或newContestsCategoriesNominationsController 中的操作?

【问题讨论】:

  • 您想以一种形式还是以多种形式创建或更新相关对象(竞赛、类别和提名)?
  • 我计划以模态形式创建/更新类别和提名,因此在关闭后会将数据传输到主表单(创建/编辑比赛页面)并保存比赛也将调用保存链接到它的类别和提名。至少这是我想到的唯一解决方案。
  • 任何答案对您有帮助吗?还是您需要更多帮助?
  • 如果我决定将类别/提名链接到单个页面上的竞赛怎么办?例如,通过定义当我在新竞赛页面上按下“添加类别”按钮时呈现的部分。

标签: ruby-on-rails model-view-controller architecture modal-dialog naming-conventions


【解决方案1】:

这完全取决于你想如何操作你的对象。如果您只想通过 Contests 修改所有属性和关系,则只需要 ContestsController。使用 accept_nested_attributes_for http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html 之类的漂亮小方法,您可以提供所有相关值,甚至是关联记录。

【讨论】:

  • accept_nested_attributes_for 被认为是有害的。它易碎且难以维护,因为它在视图中更难以耦合嵌套对象。创建表单对象(处理这些嵌套对象的类)并使用等效的控制器来表示该类是有意义的。
【解决方案2】:

参考您在 cmets 中提到的要求,我会在模态对话框中创建一个表单,它代表一个表单对象,例如:

class Nomination::Category
  extend ActiveModel::Naming
  include ActiveModel::Conversion
  include ActiveModel::Validations

  # validates :your_attributes

  def initialize(category, attributes = {})
    @category = category
    @attributes = attributes
  end

  def persisted?
    false
  end

  def save
    return false unless valid?
    if create_objects
      # after saving logic
    else
      false
    end
  end
  # more business logic according to your requirements
private
  def create_objects
    ActiveRecord::Base.transaction do
      # @category.contests = ... saving logic
      @category.save!
    end
  rescue
    false
  end
end

和一个代表控制器:

class NominationCategoriesController < ApplicationController
  def new
    category = Category.find params[:category_id]
    @nomination_category = Nomination::Category.new category
  end

 def create
   category = Category.find params[:category_id]
   @nomination_category = Nomination::Category.new category, params[:nomination_category]
   @nomination_category.save
 end
end

请注意,这只是一个示例/想法。具体实现取决于您的具体业务逻辑要求。

值得一读more about the form objects approach

【讨论】:

  • 我不明白这个结构:Nomination::Category。我将其读作“提名命名空间中的类别”。但是,相反,提名属于类别(又属于竞赛;这里类别 == ContestCategory),而不是类别到提名。
  • 好吧。如果我混淆了你的具体联想,请见谅。然后你应该反转命名空间的东西。但这个答案的关键是使用一个表单对象,它代表您的工作流程或表单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多