【问题标题】:How do I preserve the order of associations in Rails3?如何保持 Rails3 中的关联顺序?
【发布时间】:2010-12-27 21:06:34
【问题描述】:

我有一个位置数组

locations = ["california", "new york", "florida"]

我有一个名为 foobar 的模型 has_many :placesPlace 模型 belongs_to :foobar 并有一个相关列 - name:string

我有一个嵌套表单,允许我选择适用于 foobar 的位置。 为了提供选项,我根据控制器中的位置列表构建位置:

class FoobarController < ApplicationController
  def edit
    @foobar = Foobar.find(params[:id])
    APP_CONFIG['locations'].each do |location|
       @foobar.places.find_by_name(location) || @foobar.places.build(:name => location)
    end
  end
end

这几乎没有问题。我包含编辑方法的原因是因为这是有问题的方法。地点列表确实已填充,但已存在的 Foobar 地点显示在顶部。


举个例子! :)

  1. 我创建了一个新的Foobar。以我的形式 我向下滚动到地方,我看到 选项“加利福尼亚”、“纽约” 和“佛罗里达”。我检查“加利福尼亚” 和“佛罗里达”并创建 Foobar。

  2. 接下来我去编辑 Foobar。再次,我 向下滚动到这些地方,我看到了 我检查了两个选项。那是 太好了,除了顺序 出现的选项是 "california", "florida", "new york" - 选中的地方在顶部。

如何保留原始数组中位置的顺序?

谢谢!


更新:查看代码:

<%= f.fields_for :places do |place| %>
    <div class="place">
        <%= place.hidden_field :name %>
        <%= place.check_box :checked %>
        <%= place.label :checked, place.object.name %>
    </div>
<% end %>

【问题讨论】:

  • 您包含的代码并不直接控制任何东西的顺序。请发布您的查看代码。
  • 发布了代码。谢谢!

标签: ruby-on-rails view associations nested-forms


【解决方案1】:

你不能……至少不是你现在做的那样。想想 rails 做了什么。它自动按表的 id (PK) 列排序。由于您正在构建的记录不会有 id,因此它们将被放置在最后 - 每次。您可以解决并使用 CREATE 和 fudge id,但这很麻烦,可能会遇到严重的问题。

为了保持秩序(双关语),您需要某种数组指针系统:

class FoobarController < ApplicationController
  def edit
    @foobar = Foobar.find(params[:id])
    @places = Array.new
    APP_CONFIG['locations'].each do |location|
      @places << @foobar.places.build(:name => location)
    end
  end
end

然后,在您看来,您需要遍历数组并手动构建表单。我建议先查看源代码并查看嵌套表单的显示方式。

这是我的处理方法 - 每次都构建(没有 find_by_name)。然后,在您想要的模型中:

class Foo < ActiveRecord
  has_many :places

  accepts_nested_attributes_for :places, :reject_if => { |a| !APP_CONFIG['locations'].include?(a) || Place.find_by_name(a).nil? || !Place.find_by_name_and_foo_id(a, self.id).nil? }
end

现在,我实际上并没有针对您的情况测试该代码,因此我将对其进行分解;

1.) 如果提交的属性不在全局数组中,则拒绝(更多的安全问题)

2.) 如果名称不是有效的地点,则拒绝(再次,安全)

3.) 如果该 foo 的位置已经存在,则拒绝(您的类 has_many :places)

【讨论】:

  • 不方便,但可以。你提到“至少不是[我]这样做的方式。”我一开始会做错事吗?谢谢!!
【解决方案2】:

查看acts_as_list >> https://github.com/rails/acts_as_list,它将has_many集合中项目的顺序显式存储在名为“位置”的列中。

【讨论】:

    猜你喜欢
    • 2015-05-23
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 2022-12-24
    • 1970-01-01
    相关资源
    最近更新 更多