我对控制器上的每个create,update和update_status方法都执行了一项操作,但是我感到自己在重复自己的工作,并且非常感谢您提供了一些更好的编写方法的帮助。
我已经将更新逻辑抽象为服务,但是在控制器的每个方法上,参数都是不同的。
def create
@story = Story.new(story_params)
@story.creator = current_user
if @story.save
next_state = StoryStateService.new(@story, current_user, nil).call
if next_state
@story.update_column(:status_id, next_state)
end
redirect_to stories_path
else
render 'stories/new'
end
end
def update
@story = Story.find(params[:id])
if @story.update(story_params)
next_state = StoryStateService.new(@story, current_user, nil).call
if next_state
@story.update_column(:status_id, next_state)
end
redirect_to stories_path
else
render 'edit'
end
end
def update_story_status_event
story = Story.find(params['story_id'])
sub_action = params['sub_action']
next_state = StoryStateService.new(story, current_user, sub_action).call
if next_state
story.update_column(:status_id, next_state)
end
redirect_to stories_path
end
如您所见,我有
next_state = StoryStateService.new(story, current_user, sub_action).call
if next_state
story.update_column(:status_id, next_state)
end
在三种方法上重复,但是在常规创建和更新时,我不需要发送sub_action参数(字符串)。
答案 0 :(得分:0)
我不确定StoryStateService
在做什么,但是如果它正在处理更新许多模型的问题,那么您还可以制作一个模块或类并将其放在lib
目录中。 / p>
另一个选择是(对于Story.find()
可能更优选)是使用before_action
回调。 (https://apidock.com/rails/v4.0.2/AbstractController/Callbacks/ClassMethods/before_action)
例如
在Story.find()
和update
中使用update_story_status_event
时,您可以执行以下操作:
before_action :find_story, :only => [:update, :update_story_status_event]
def find_story
@story = Story.find(params[:id])
rescue ActiveRecord::RecordNotFound
# handle error here
end
答案 1 :(得分:0)
考虑到其他所有内容的简单性,我只会讲故事的进展,这对我来说是过大的。
def create
@story = Story.new(story_params)
@story.creator = current_user
if @story.save
advance_story @story
redirect_to stories_path
else
render 'stories/new'
end
end
def update
@story = Story.find(params[:id])
if @story.update(story_params)
advance_story @story
redirect_to stories_path
else
render 'edit'
end
end
def update_story_status_event
story = Story.find(params['story_id'])
sub_action = params['sub_action']
advance_story story, sub_action
redirect_to stories_path
end
private
def advance_story(story, sub_action = nil)
next_state = StoryStateService.new(story, current_user, sub_action).call
if next_state
story.update_column(:status_id, next_state)
end
end