有关NestedIterators的解决方案

时间:2017-03-27 03:54:44

标签: ruby ruby-on-rails-5

我是日本人。请原谅我的英语不好。(感谢gxxgle翻译。)

当我的代码被RubyCritic / Reek的NestedIterators指出时,我该如何解决?请告诉我可用的解决方案。

例如, 1)使用map等降低嵌套级别, 2)设计使得它通过调用集合元素的方法而不是操纵集合元素的元素来完成。

我的代码由RubyCritic / Reek的NestedIterators指出:

def check_in_hotel_bookings_all
  set_booking
  @booking.hotel_bookings.each do |hotel_booking|
    hotel_booking.checked_in_at = Time.now
    hotel_booking.save
    hotel_booking.hotel_bookings_customers.each do |customer|
 NestedIterators
BookingsController#check_in_hotel_bookings_all contains iterators nested 2 deep

      customer.checked_in_at = hotel_booking.checked_in_at
      customer.save
    end
  end
  render json: true
end

我试图这样做:

booking.hotel_bookings.map(&:customers).map(&check_in_now)
booking.hotel_bookings.map(&:check_in_now).map(&:save)

1 个答案:

答案 0 :(得分:0)

最好使用简单的方法并使用较少的链接和较少的迭代器。所以this.map(&:thing).map(&:other_thing).map(&:third_thing)很难理解,也很难编写测试。

将代码移至模型

@booking.hotel_bookings.each do |booking|
  booking.check_in_all_customers!(Time.now.utc)
end
render json: true

模特HotelBooking

def check_in_all_customers!(time)
  self.checked_in_at = time
  save!
  hotel_bookings_customers.each do |customer|
    customer.checked_in_at = time
    customer.save
  end
end

或者您可以将方法check_in_all_customers添加到has_many关联 -

HotelBooking.has_many :hotel_bookings_customers do
  def check_in_all(time)
    proxy_association.target.each do |customer| 
      customer.checked_in = time
      customer.save
    end
  end
end

控制器

@booking.hotel_bookings_customers.check_in_all(Time.now)

当你全部展开它时,它的迭代次数和嵌套次数相同,但它更容易理解,也更容易编写测试。