如何在Ruby中为'每个循环'创建这个?

时间:2016-01-27 12:40:00

标签: ruby loops ruby-on-rails-4

假设:

class Author < ActiveRecord::Base
  has_many :articles
end

收到包含作者文章的JSON文件后,我想销毁作者数据库中的文章,但不包含在JSON文件中。如何为每个循环创建“?”

article_collection = @author.articles.all
unless article_collection.blank?
  article_collection.each do |article_from_collection|
    # How can I check on the next line if it's id is included in the params?
    if article_from_collection.arti_id "is not part of" params[:author][:articles_attributes]
      article_from_collection.destroy
    end
  end
end

如何根据参数中包含的arti_id检查第5行,JSON输入中是否存在arti_id的文章?

我是否应该在参数中构建arti_id的集合,然后使用.include?查看数据库中的每篇文章,如果它在此集合中?

我尝试了以下两行。第一个返回false,无论文章是否包含在json中。第二行返回错误TypeError Exception: no implicit conversion of Symbol into Integer

if params[:author][:articles_attributes].include? article_from_collection.arti_id
if params[:author][:articles_attributes][:arti_id].include? article_from_collection.arti_id

params[:author]返回类似的内容:

{ "some_other_attributes"=>[ {"key"=>"value", ...},
                             {...} ],
  "articles_attributes"=>  [ {"arti_id"=>"string-id", "other_attributes"=>"value", ...},
                             {"arti_id"=>"string-id", "other_attributes"=>"value", ...} ]
}

4 个答案:

答案 0 :(得分:6)

您可以使用ActiveRecord查询执行此操作

article_ids = params[:author][:article_attributes].map do |attrs|
  attrs[:arti_id]
end

@author.articles.where.not(id: article_ids).destroy_all

这会破坏作者的所有文章,这些文章的ID不在您给出的文章属性中。

如果您对查询感到困惑,它只会创建一个NOT IN查询,过滤掉传入的文章,然后销毁剩下的文章。

答案 1 :(得分:2)

为此,您可以先在单独的数组变量中映射出所有arti_id,然后使用include? methodexclude? method检查特定的ID是否在数组中

示例:

article_ids = params[:author][:articles_attributes].map{ |art_attr| art_attr[:arti_id] }

然后在循环中:(使用include?方法)

article_collection = @author.articles.all
unless article_collection.blank?
  article_collection.each do |article_from_collection|
    # This is how you can handle it...
    unless article_ids.include? article_from_collection.arti_id 
      article_from_collection.destroy
    end
  end
end

或者您是否愿意使用exclude

article_collection = @author.articles.all
unless article_collection.blank?
  article_collection.each do |article_from_collection|
    # This is how you can handle it...
    if article_ids.exclude? article_from_collection.arti_id 
      article_from_collection.destroy
    end
  end
end

答案 2 :(得分:2)

如下所示:

article_collection = @author.articles.all
params_article_ids = params[:author][:articles_attributes].collect{ |article_attrs| article_attrs[:arti_id]}

article_collection.reject{ |art| present_article_ids.include?(art.id)}.each(&:destroy)

答案 3 :(得分:2)

我假设您的params [:author] [:articles_attributes]包含文章属性的哈希值,其中每个属性都有一个arti_id。

首先,我会返回作者的所有文章ID:

all_article_ids = @author.articles.pluck(:arti_id)

其次,我从您要保存的文章属性中收集所有arti_ids:

ids = params[:author][:articles_attributes].map{|attr| attr.arti_id}

现在有两个ID数组。我从“all_article_ids”中减去“ids”数组,然后得到一个新的id数组,这些数组不在“ids”数组中。这些是“all_article_ids”的ID,应该被销毁。

@author.articles.destroy(all_article_ids - ids)

这适合您的需求吗?