우려에 대한 보수적 사례

6442 단어 railscodequalityruby
Rails 프로젝트에서 우려의 사용을 비난하는 많은 기사가 있으며 모두 유효한 요점을 가지고 있습니다.
양방향 종속성을 유발하고 임의로 코드를 여러 파일로 분할하는 것과 같은 주장에 대부분 동의합니다.
그렇긴 하지만, 이러한 기사 중 많은 부분이 우려 사항을 사용해서는 안 된다고 주장하는 것은 너무 지나치다고 생각합니다.

분명히 하자면, 20개의 우려로 시작하는 모델이 포함되어 있는 것을 본다면 저는... 글쎄요, 걱정됩니다.
이것이 내가 우려에 대한 보수적인 사례라는 제목을 붙인 이유입니다.
아주 아껴서 사용해야 한다고 생각하지만 코로나바이러스처럼 피해서는 안 됩니다.

즉, 우려 사항이 기존 모델의 특정 방법이나 속성에 의존하지 않고 비즈니스 요구 사항과 함께 발전할 가능성이 있고 완전히 다른 프로젝트에서 사용될 수 있는 코드를 포함하지 않을 때 유효할 가능성이 높습니다. 우려에 사용합니다.

최근에 관련 CSV 파일을 가져와야 하는 프로젝트를 진행하고 있었습니다.
이 파일에서 연결은 레코드 이름을 기반으로 수행되었습니다.
예를 들어 기사에 대한 CSV 파일이 있고 각 기사가 작성자에게 속한 경우 CSV에는 "Keeyan Nejad"라는 이름을 가질 수 있는 작성자 열이 있습니다.
그런 다음 작성자 CSV에 이름을 포함하는 이름 열이 있습니다(이 예에서는 모든 작성자가 고유한 이름을 가지고 있다고 가정).

CSV를 가져올 때 작성자 모델은 이름 열에서 이름을 가져옵니다.
그런 다음 기사를 가져오지만 기사를 작성자와 연결할 때가 되면 ID가 아니라 작성자 이름만 갖게 됩니다.
이 문제를 해결하려면 다음과 같이 작성해야 합니다.

Article.create(
  title: csv_row['title'],
  content: csv_row['content'],
  author: Author.find_by(name: csv_row['author'])
)

나쁘지는 않지만 작성자는 국가에 속해 있으며 국가 ID 대신 국가 이름이 있습니다.

따라서 Authors를 가져오려면 다음을 수행해야 합니다.

Author.create(
  name: csv_row['name'],
  country: Country.find_by(name: csv_row['country'])
)

나는 이것을 조금 정리하고 싶었고 이것이 Rails 문제에 대한 유효한 용도를 찾은 곳입니다.
ID 열이 아닌 이름으로 레코드를 연결하는 방법을 원했습니다.

약간의 플레이를 한 후 다음 코드를 생각해 냈습니다.

module AssociableByName
  extend ActiveSupport::Concern

  included do
    def self.associate_by_name(model)
      define_setter_for_model(model)
    end

    def self.define_setter_for_model(model)
      define_method("#{model}_name=") do |reference|
        association_class = self.class.reflect_on_association(model).klass
        association = association_class.find_by(name: reference)
        raise "Could not find #{model} by name #{reference}" if association.nil?

        send("#{model}=", association)
      end
    end
  end
end

그런 다음 기사 모델에서 다음 줄을 추가합니다.

include AssociableByName
associate_by_name :author

이 코드가 하는 일은 author_name=라는 모델에 새로운 setter를 생성하는 것입니다. 이 setter는 단순히 이름에서 작성자 ID를 가져오고 연결을 생성합니다.

그 변경으로 더 일관되게 작동하도록 임포터를 업데이트할 수 있습니다.

Article.create(
  title: csv_row['title'],
  content: csv_row['content'],
  author_name: csv_row['author']
)

그리고 그게 다야!
이제 기사는 조회를 수행할 필요 없이 이름으로 작성자와 자동으로 연결되며 연결이 존재하지 않는 경우 오류가 발생한다는 추가 이점도 얻습니다(다음과 같은 경우 author_id 아이디가 존재하지 않음)

어떻게 생각해? 나는 잘못된 것으로 판명되어 기쁩니다. 이 코드가 좋은 관심사가 아닌 이유를 알게 되어 기쁩니다. 생각이 있으면 알려주세요!

좋은 웹페이지 즐겨찾기