模型 before_save 未使用来自 params/controller 的更新的多选顺序
Model before_save not using updated multiselect order coming from params/controller
在表单中,我有一个可以手动排序的多选下拉列表。当我在编辑时提交表单时,我在参数中得到以下内容:
"article" =>{"tag_ids"=>["", "4", "1", "2"]}
哪个是我想要的,而不是1、2、4。
然后,我在模型中更新序号。我无法从参数中获取 tag_id 的新订单。当我调用 article_tags 时,我得到 table 的顺序,而不是参数中的顺序。我假设这是因为 tag_ids 没有变化(相同的条目,不同的顺序)。有没有一种方法可以在模型本身中访问该订单?
我可以使用隐藏输入或 attr_accessors 做一些变通方法,但我想知道是否有办法从模型中做到这一点。
控制器:
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
您可以通过重写 tag_ids=
setter 创建的方法来做到这一点 has_many: :tags, through: :article_tags
。
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
在表单中,我有一个可以手动排序的多选下拉列表。当我在编辑时提交表单时,我在参数中得到以下内容:
"article" =>{"tag_ids"=>["", "4", "1", "2"]}
哪个是我想要的,而不是1、2、4。
然后,我在模型中更新序号。我无法从参数中获取 tag_id 的新订单。当我调用 article_tags 时,我得到 table 的顺序,而不是参数中的顺序。我假设这是因为 tag_ids 没有变化(相同的条目,不同的顺序)。有没有一种方法可以在模型本身中访问该订单?
我可以使用隐藏输入或 attr_accessors 做一些变通方法,但我想知道是否有办法从模型中做到这一点。
控制器:
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
您可以通过重写 tag_ids=
setter 创建的方法来做到这一点 has_many: :tags, through: :article_tags
。
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