Rails3 Conditional Statements in Controller Actions
I'm trying to write a conditional statement in my tasks controllers for a simple rails3 application.
Users have many tasks and tasks have one user.
When creating a task, we can chose who owns it:
<%= collection_select(:task, :user_id, User.all, :id, :name, {:prompt => true}) %>
I want the system to se开发者_如何转开发nd an email to the owner of the task, only when it's created for someone else. I.e. I do not need to receive an email when I create a task for myself.
My mailer's working fine and in my tasks controller, I've tried this:
def create
@task = Task.new(params[:task])
respond_to do |format|
if @task.save and @task.user_id = current_user.id
format.html { redirect_to(tasks_path, :notice => 'Task was successfully created.') }
format.xml { render :xml => @task, :status => :created, :location => @task }
elsif @task.save
format.html { redirect_to(tasks_path, :notice => 'Task was successfully created.') }
format.xml { render :xml => @task, :status => :created, :location => @task }
TaskMailer.new_task(@task).deliver
else
format.html { render :action => "new" }
format.xml { render :xml => @task.errors, :status => :unprocessable_entity }
end
end
end
But it's not really working... Any chance of some assistance.
Replace @task.user_id = current_user.id
with @task.user_id == current_user.id
.
This is not the cause of your error, but you're saving your task two times if @task.user_id != current_user.id
. You could do something like this instead:
def create
@task = Task.new(params[:task])
respond_to do |format|
if @task.save
format.html { redirect_to(tasks_path, :notice => 'Task was successfully created.') }
format.xml { render :xml => @task, :status => :created, :location => @task }
TaskMailer.new_task(@task).deliver if @task.user_id != current_user.id
else
format.html { render :action => "new" }
format.xml { render :xml => @task.errors, :status => :unprocessable_entity }
end
end
end
end
Are you not storing the id of the creator? If you do, all the data you need is in the model. Thus just implement an private instance method in Task model. Something like the following
# Task model
private
def notify_assignee
if new_record? || user_id_changed? && creator_id != user_id
TaskMailer.new_task(@task).deliver
end
end
Call the above method after_save
# Task model
after_save :notify_assignee
In case you are not storing the creator_id in the database, create an attribute accesor called :creator_id
.
# Task model
attr_accessor :creator_id
In the controller, before saving, do
# Tasks controller
@task.creator_id = current_user.id
and the above method would still work.
You controller re directions would automatically be simplified to
if @task.save
format.html { redirect_to(tasks_path, :notice => 'Task was successfully created.') }
format.xml { render :xml => @task, :status => :created, :location => @task }
else
format.html { render :action => "new" }
format.xml { render :xml => @task.errors, :status => :unprocessable_entity }
end
And also this would be the right way to go as the "business logic" (which in your case is send assignee an email notifying that someone else has assigned a task to them) would reside in the model.
It's because of this line, you're using an assignment =
instead of the comparision ==
Also the current_user should be @current_user
instead because you didn't specify it in the method. (Or you have a method current_user()
that you did not post. Then it's fine)
if @task.save and @task.user_id = current_user.id
It should be
if @task.save and @task.user_id == @current_user.id
also imho you should move the mailing-stuff to the Task
-model and use an after_save
-callback.
Maybe you need change this line: @task.user_id = current_user.id
to @task.user_id == current_user.id
精彩评论