I have a task
model which is related to the user
and project
models.
When I create/update a task, I need to do an update in the view async, not only for the task change/addition, but to the project and user info (because some of that data might change too).
I have this in the controller:
def create
@task = Task.new(params[:task])
@project = Project.find(params[:project_id])
respond_to do |format|
if @task.save
format.html { redirect_to @task, notice: 'Task was successfully created.' }
format.json { render json: @task, status: :created, location: @task }
else
format.html { render action: "new" }
format.json { render json: @task.errors, status: :unprocessable_entity }
end
end
end
And my tasks/create.js.coffee
# Update task table
$('#mytable').append("<%= j render(partial: 'tasks/task', locals: { t: @task }) %>")
# Update user data
$('.user-data').html("<%= j render(partial: 'users/user_widget', locals: { u: current_user }) %>")
# Update project data
$('.project-data').html("<%= j render(partial: 'projects/project_widget', locals: { p: @project }) %>")
And it works great. I see 2 issues:
In every render of .js.coffee
I add, I am repeating the code too much. I duplicate exactly the same code for updating project and user data, on tasks update, tasks destroy, and I would do the same for a new model which might affect the user and the project
It seems weird to handle project and user data in tasks/create.js.coffee
Therefore, I am looking for a better pattern to handle this stuff, any ideas?
EDIT (to clarify): I think achieving something like this would be better:
tasks/create.js.coffee
# Update task table
$('#mytable').append("<%= j render(partial: 'tasks/task', locals: { t: @task }) %>")
UserData.refresh()
ProjectData.refresh()
However, I can't do that because I need to render the partial each time, so I would have to do something weird like passing the html partial to those refresh()
functions, and it would be pretty the same as the previous way.
This is just a way that came to my mind, but I would like to hear your ideas if any.
You could render a template/action that belongs to a different controller. So you could keep the tasks/create.js.coffee file and for all the other controller actions (like users and projects) that use the same code, in your respond_to block you would use:
format.json { render 'tasks/create' }
You could even render a specific file:
format.json { render file: "path/to/specific/file" }
Here is a link with more information on rendering in rails: http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-an-action-s-template-from-another-controller
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With