Reputation: 35349
Assume you have a Question
and an Answer
models, and that new answers are submitted from the questions#show
page (like StackoverFlow).
Unless the questions#show
and the answers#create
actions load identical data, the answers#create
will throw an exception (usually no method on nil class) if there is a validation error on a new answer. It's not a major issue, but when you add filters and other types of data, the code starts to smell, and you get tight coupling between both actions. Changing one requires changing the other--something easy to forget.
I'm wondering what do experienced Rails developers do, if anything, to avoid this coupling?
# 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
Now let's look at the responses#create
action, which has to load the same data for render
to work (if validation fails):
# 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
Upvotes: 1
Views: 217
Reputation: 1059
It seems like your issue is that you have very tight coupling between unrelated controller actions, since the answers#create is trying to be a discussions#show as well.
One option is to redirect to @discussion on validation errors as well as success, and pass in the submitted answer parameters to the redirect. Then you can handle the "special" case that there is answer data in the question show action.
Upvotes: 1