Ruby 保存前的模型不使用来自params/controller的更新的多选顺序

Ruby 保存前的模型不使用来自params/controller的更新的多选顺序,ruby,ruby-on-rails-5,Ruby,Ruby On Rails 5,在表单中,我有一个可以手动排序的多选下拉列表。当我在编辑时提交表单时,我在参数中得到以下信息: "article" =>{"tag_ids"=>["", "4", "1", "2"]} 这是我想要的,而不是1,2,4 然后,在模型中更新序号。我无法从参数中获取tag_id的新顺序。当我调用article_标记时,我得到的是表的顺序,而不是参数中的顺序。我假设这是因为tag_id没有变化(相同的条目,不同的顺序)。有没有一种方法可以访问模型本身的顺序 我可以使用隐藏输入或attr_访

在表单中,我有一个可以手动排序的多选下拉列表。当我在编辑时提交表单时,我在参数中得到以下信息:

"article" =>{"tag_ids"=>["", "4", "1", "2"]}
这是我想要的,而不是1,2,4

然后,在模型中更新序号。我无法从参数中获取tag_id的新顺序。当我调用article_标记时,我得到的是表的顺序,而不是参数中的顺序。我假设这是因为tag_id没有变化(相同的条目,不同的顺序)。有没有一种方法可以访问模型本身的顺序

我可以使用隐藏输入或attr_访问器来解决一些问题,但我想知道是否有一种方法可以从模型中实现

控制器:

def update
 if @article.update(article_params)
  redirect_to articles_path
 end
end

def article_params
 params.require(:article).permit(:title, tag_ids: [])
end
型号:

class Article
 has_many: :article_tags
 has_many: :tags, through: :article_tags

 before_save: :order

 def order
  self.article_tags.each_with_index do |i, idx|
   i.update_attribute(:ordinal, idx) 
  end
 end
end

class ArticleTag
 belongs_to: :article
 belongs_to: :tag
end
桌子

articles
 id  |   title
------------------
  1  |  Testing

tags
 id  |   name
------------------
  1  |  Business
  2  |  Education
  3  |  Health
  4  |  Social

article_tags
 id  |   article_id  |  tag_id  | ordinal
------------------------------------------
  1  |       1       |     1    |   2
  2  |       1       |     2    |   3
  3  |       1       |     4    |   1

您可以通过覆盖
has\u many::tags通过::article\u tags创建的
setter方法来实现这一点

class Article
  # ...
  def tags_ids=(ids)
    ids.reject(&:blank?).each_with_index do |id, index|
      article_tag = self.article_tags.find_or_intialize_by(tag_id: id)
      article_tag.update(
        ordinal: index
      )
      article_tag.where.not(tag_id: ids).destroy_all
    end
  end
end