干燥此 Ruby 代码
DRYing this Ruby code
最近,我开始使用 Rubocop,并一直在努力思考我的代码是否可以写得更好。我有一个非常相似的创建和更新方法。 Rubocop 抱怨该方法的代码行太多 [12/10]。我想知道您将如何在这里遵循 DRY 原则。在我看来, respond_to 应该被带到它自己的私有方法中。但我不知道什么是最好的方法,因为:
- 闪光可以是:成功或:危险
- 一个检查模型是否保存,另一个检查模型是否更新。
- 不同的渲染取决于模型是否保存或是否有错误
我也不知道我是否应该让它一个人呆着。不过,它是如此多余的事实确实让我着迷。最终我想要最干净的代码,我只是不确定我是否应该 DRY 这个方法
def create
@category = Category.new(category_params)
respond_to do |format|
if @category.save
flash[:success] = 'Category Successfully Created'
format.html { redirect_to admin_category_path(@category) }
format.json { render :show, status: :created, location: @category }
else
flash[:danger] = 'Errors in creating category, see below'
format.html { render :new }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end
def update
@category = Category.find(params[:id])
respond_to do |format|
if @category.update(category_params)
flash[:success] = 'Category Successfully updated!'
format.html { redirect_to admin_category_path(@category) }
format.json { render :show, status: :created, location: @category }
else
flash[:danger] = 'Errors in updating category, missing information'
format.html { redirect_to action: 'edit', id: @category.id }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end
尝试从 create
和 update
中创建一个方法没有任何意义,因为它们有两个截然不同的目的。
相反,您可以考虑以下事项:
- 你真的需要 json 格式吗?如果你不使用它,你可以安全地删除那些行;
从 update
中删除 @category = Category.find(params[:id])
并将其移动到 before_action
中的方法
before_action :find_category, only: [:edit, :update]
def find_category
@category = Category.find(params[:id])
end
最后但同样重要的是,Rubocop 并不总是有正确的答案:专注于清晰!
除了消息中的单个单词外,所有成功处理都是相同的; JSON 对错误的处理是相同的。因此,这些部分可以提取到由 create 和 update 调用的方法中。不仅代码会更简洁,而且 reader 哪些行为相同,哪些行为不同也会一目了然。我没有 运行 或测试过这段代码,但它是:
def handle_success(created_or_updated)
verb = created_or_updated == :created ? 'Created' : 'Updated'
flash[:success] = "Category Successfully #{verb}"
format.html { redirect_to admin_category_path(@category) }
format.json { render :show, status: :created, location: @category }
end
def handle_failure_json
format.json { render json: @category.errors, status: :unprocessable_entity }
end
def create
@category = Category.new(category_params)
respond_to do |format|
if @category.save
handle_success(:created)
else
flash[:danger] = 'Errors in creating category, see below'
format.html { render :new }
handle_failure_json
end
end
end
def update
@category = Category.find(params[:id])
respond_to do |format|
if @category.update(category_params)
handle_success(:updated)
else
flash[:danger] = 'Errors in updating category, missing information'
format.html { redirect_to action: 'edit', id: @category.id }
handle_failure_json
end
end
end
看看这里,这是最佳做法
http://edgeapi.rubyonrails.org/classes/ActionController/Responder.html
最近,我开始使用 Rubocop,并一直在努力思考我的代码是否可以写得更好。我有一个非常相似的创建和更新方法。 Rubocop 抱怨该方法的代码行太多 [12/10]。我想知道您将如何在这里遵循 DRY 原则。在我看来, respond_to 应该被带到它自己的私有方法中。但我不知道什么是最好的方法,因为:
- 闪光可以是:成功或:危险
- 一个检查模型是否保存,另一个检查模型是否更新。
- 不同的渲染取决于模型是否保存或是否有错误
我也不知道我是否应该让它一个人呆着。不过,它是如此多余的事实确实让我着迷。最终我想要最干净的代码,我只是不确定我是否应该 DRY 这个方法
def create
@category = Category.new(category_params)
respond_to do |format|
if @category.save
flash[:success] = 'Category Successfully Created'
format.html { redirect_to admin_category_path(@category) }
format.json { render :show, status: :created, location: @category }
else
flash[:danger] = 'Errors in creating category, see below'
format.html { render :new }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end
def update
@category = Category.find(params[:id])
respond_to do |format|
if @category.update(category_params)
flash[:success] = 'Category Successfully updated!'
format.html { redirect_to admin_category_path(@category) }
format.json { render :show, status: :created, location: @category }
else
flash[:danger] = 'Errors in updating category, missing information'
format.html { redirect_to action: 'edit', id: @category.id }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end
尝试从 create
和 update
中创建一个方法没有任何意义,因为它们有两个截然不同的目的。
相反,您可以考虑以下事项:
- 你真的需要 json 格式吗?如果你不使用它,你可以安全地删除那些行;
从
中的方法update
中删除@category = Category.find(params[:id])
并将其移动到before_action
before_action :find_category, only: [:edit, :update] def find_category @category = Category.find(params[:id]) end
最后但同样重要的是,Rubocop 并不总是有正确的答案:专注于清晰!
除了消息中的单个单词外,所有成功处理都是相同的; JSON 对错误的处理是相同的。因此,这些部分可以提取到由 create 和 update 调用的方法中。不仅代码会更简洁,而且 reader 哪些行为相同,哪些行为不同也会一目了然。我没有 运行 或测试过这段代码,但它是:
def handle_success(created_or_updated)
verb = created_or_updated == :created ? 'Created' : 'Updated'
flash[:success] = "Category Successfully #{verb}"
format.html { redirect_to admin_category_path(@category) }
format.json { render :show, status: :created, location: @category }
end
def handle_failure_json
format.json { render json: @category.errors, status: :unprocessable_entity }
end
def create
@category = Category.new(category_params)
respond_to do |format|
if @category.save
handle_success(:created)
else
flash[:danger] = 'Errors in creating category, see below'
format.html { render :new }
handle_failure_json
end
end
end
def update
@category = Category.find(params[:id])
respond_to do |format|
if @category.update(category_params)
handle_success(:updated)
else
flash[:danger] = 'Errors in updating category, missing information'
format.html { redirect_to action: 'edit', id: @category.id }
handle_failure_json
end
end
end
看看这里,这是最佳做法
http://edgeapi.rubyonrails.org/classes/ActionController/Responder.html