简体   繁体   中英

Metrics/AbcSize: Assignment Branch Condition size for fill_arrays is too high. [<9, 21, 0> 22.85/17]

I need to generate random data with ffaker and have no clue how to fix abcsize here

Here is what i had

class Library
  attr_accessor :authors, :books, :orders, :readers

  def initialize(authors = [], books = [], orders = [], readers = [])
    @books = books
    @orders = orders
    @readers = readers
    @authors = authors
  end

  def create_data
    @authors = []
    @books = []
    @readers = []
    @orders = []

    100.times do
      authorname = FFaker::Book.author
      biography = FFaker::Book.description
      title = FFaker::Book.title
      name = FFaker::Name.name
      email = FFaker::Internet.email
      city = FFaker::Address.city
      street = FFaker::Address.street_name
      house = rand(1 - 10_000)
      date = Time.now.utc.strftime('%d.%m.%Y')

      @authors.push(Author.new(authorname, biography))
      @books.push(Book.new(title, authorname))
      @readers.push(Reader.new(name, email, city, street, house))
      @orders.push(Order.new(title, name, date))
    end
  end
end

So i decided to create few private methods but still have big abcsize

class Library
  attr_accessor :authors, :books, :orders, :readers

  def initialize(authors = [], books = [], orders = [], readers = [])
    @books = books
    @orders = orders
    @readers = readers
    @authors = authors
  end

  def create_data
    create_arrays
    fill_arrays
  end
   
  private

  def create_arrays
    @authors = []
    @books = []
    @readers = []
    @orders = []
  end

  def fill_arrays
    100.times do
      authorname = FFaker::Book.author
      biography = FFaker::Book.description
      title = FFaker::Book.title
      name = FFaker::Name.name
      email = FFaker::Internet.email
      city = FFaker::Address.city
      street = FFaker::Address.street_name
      house = rand(1 - 10_000)
      date = Time.now.utc.strftime('%d.%m.%Y')

      @authors.push(Author.new(authorname, biography))
      @books.push(Book.new(title, authorname))
      @readers.push(Reader.new(name, email, city, street, house))
      @orders.push(Order.new(title, name, date))
    end
  end
end

I can't really separate that ffaker part because:

  1. Author from Books must be an instance of Author class.
  2. Book from Orders, must be an instance of Book class.

Would really appreciate if someone could help me, don't have much experience at refactoring

Method separation partially worked as @Sergii-k suggested but now i have some troubles with associations

class Library
  attr_accessor :authors, :books, :orders, :readers

  def initialize(authors: [], books: [], orders: [], readers: [])
    @books = books
    @orders = orders
    @readers = readers
    @authors = authors
  end

  def create_arrays
    @authors = []
    @books = []
    @readers = []
    @orders = []
  end

  def create_data
    create_arrays
    fill_arrays
  end

  def show
    create_data
    puts @authors
    puts @books
    puts @orders
    puts @readers
  end

  def build_author
    name = FFaker::Book.author
    biography = FFaker::Book.description
    Author.new(name, biography)
  end

  def build_book(author)
    title = FFaker::Book.title
    Book.new(title, author.name)
  end

  def build_reader
    name = FFaker::Name.name
    email = FFaker::Internet.email
    city = FFaker::Address.city
    street = FFaker::Address.street_name
    house = rand(1 - 10_000)
    Reader.new(name, email, city, street, house)
  end

  def build_order(reader)
    date = Time.now.utc.strftime('%d.%m.%Y')
    title = FFaker::Book.title
    Order.new(title, reader.name, date)
  end

  def fill_arrays
    1.times do
      author = build_author
      reader = build_reader

      @authors.push(author)
      @books.push(build_book(author))
      @readers.push(reader)
      @orders.push(build_order(reader))
    end
  end
end

 

This is the problem part now

  def build_book(author)
    title = FFaker::Book.title
    Book.new(title, author.name)
  end

  def build_order(reader)
    date = Time.now.utc.strftime('%d.%m.%Y')
    title = FFaker::Book.title
    Order.new(title, reader.name, date)
  end

I get 2 different titles now because i generate them in both methods. Tried to pass an arguments but it didn't work

  def build_order(book, reader)
    date = Time.now.utc.strftime('%d.%m.%Y')
    Order.new(book.title, reader.name, date)
  end

Done, works well!

class Library
  attr_accessor :authors, :books, :orders, :readers

  def initialize(authors: [], books: [], orders: [], readers: [])
    @books = books
    @orders = orders
    @readers = readers
    @authors = authors
  end

  def create_arrays
    @authors = []
    @books = []
    @readers = []
    @orders = []
  end

  def create_data
    create_arrays
    fill_arrays
  end

  def show
    create_data
    puts @authors
    puts @books
    puts @orders
    puts @readers
  end

  def build_author
    name = FFaker::Book.author
    biography = FFaker::Book.description
    Author.new(name, biography)
  end

  def build_book(author)
    title = FFaker::Book.title
    Book.new(title, author.name)
  end

  def build_reader
    name = FFaker::Name.name
    email = FFaker::Internet.email
    city = FFaker::Address.city
    street = FFaker::Address.street_name
    house = rand(1 - 10_000)
    Reader.new(name, email, city, street, house)
  end

  def build_order(book, reader)
    date = Time.now.utc.strftime('%d.%m.%Y')
    Order.new(book.title, reader.name, date)
  end

  def fill_arrays
    1.times do
      author = build_author
      reader = build_reader
      book   = build_book(author)

      @authors.push(author)
      @books.push(book)
      @readers.push(reader)
      @orders.push(build_order(book, reader))
    end
  end
end

Here is log from yml file

--- !ruby/object:Library
books:
- !ruby/object:Book
  title: Case of the Missing Hungry Imp
  author: Twila Mante
orders:
- !ruby/object:Order
  book: Case of the Missing Hungry Imp
  reader: Monty Feeney
  date: 19.03.2021
readers:
- !ruby/object:Reader
  name: Monty Feeney
  email: lamonica.friesen@williamson.com
  city: Croninport
  street: Pfeffer Neck
  house: 3002
authors:
- !ruby/object:Author
  name: Twila Mante
  biography: Ut porro deserunt voluptatem velit. Atque dicta labore ratione minima
    sapiente. Dolor doloremque dolorem harum sint. At voluptatum molestias adipisci
    vero. Perspiciatis rerum nesciunt maiores vitae.

You can go further with method separation:

def build_author
  # ...
  Author.new(authorname, biography)
end

def build_book(author)
  # ...
  Book.new(title, author.authorname)
end

def build_reader
  # ...
  Reader.new(name, email, city, street, house)
end

def build_order(book, reader)
  # ...
  Order.new(book.title, reader.name, date)
end

def fill_arrays
  100.times do
    author = build_author
    reader = build_reader
    book   = build_book(author)

    @authors.push(build_author)
    @books.push(book)
    @readers.push(reader)
    @orders.push(build_order(book, reader))
  end
end

UPDATE: I've noticed, that some parameters are shared across methods. You can pass them as an arguments.

UPDATE: Fixed book title.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM