假设你有一个Question
和一个Answer
模型,并且新的答案是从questions#show
页面提交的(比如 StackoverFlow)。
除非questions#show
和answers#create
动作加载相同的数据,answers#create
否则如果新答案出现验证错误,则将抛出异常(通常在 nil 类上没有方法)。这不是一个主要问题,但是当您添加过滤器和其他类型的数据时,代码会开始产生异味,并且您会在两个操作之间获得紧密耦合。改变一个需要改变另一个——这很容易忘记。
我想知道有经验的 Rails 开发人员会做些什么来避免这种耦合?
# Assume Discussion = Question, and Response = Answer
# Discussions#show
def show
@discussion = Discussion.find(params[:id]) # The question
@responses = @discussion.responses.includes(:author) # Existing answers
@response = @discussion.responses.build # New answer object for the form
order = 'users.role'
if params[:filter].present?
order = case params[:filter]
when 'new'
then 'responses.created_at DESC'
end
end
@responses = @responses.order(order)
end
现在让我们看看这个responses#create
动作,它必须加载相同的数据render
才能工作(如果验证失败):
# Responses#create
def create
# @discussion is loaded using a before filter
@response = @discussion.responses.build(params[:response])
@response.author = current_user
@responses = @discussion.responses.includes(:author)
order = 'users.role'
if params[:filter].present?
order = case params[:filter]
when 'new'
then 'responses.created_at DESC'
end
end
@responses = @responses.order(order)
respond_to do |format|
if @response.save
format.html { redirect_to @discussion }
format.js
else
format.html { render 'discussions/show' } # fails if discussions#show and responses#new do not load the same data.
end
end
end