In my Rails app users can create submissions, and each submission has a title and content. Right now in the create action of of my submissions controller, it'll check to see if there are any submissions in the database that match the title of the new submission being created. If there is one in the db with the same title, it will update the one already in the db instead of creating another.
I'd like to continue to do that, however, if the value of the :title attribute is NULL (aka they didn't enter anything), I'd like it to go ahead and create a new instance REGARDLESS of if there's another instance in the db with the :title value of NULL.
Here's my attempt, which doesn't work:
def create
ajax_title = params[:title]
ajax_content = params[:content]
ajax_folder = params[:folder_id]
ajax_parent = params[:parent_id]
ajax_children = Array(params[:children])
#submissions = Submission.where(title: ajax_title)
if #submissions.empty?
#submission = Submission.create({title: ajax_title, content: ajax_content, user_id: current_user.id, folder_id: ajax_folder, parent_id: ajax_parent, children: ajax_children})
else
if #submissions.blank?
#submission = Submission.create({title: ajax_title, content: ajax_content, user_id: current_user.id, folder_id: ajax_folder, parent_id: ajax_parent, children: ajax_children})
else
#submissions[0].content = ajax_content
#submissions[0].save
end
end
end
How do I check and ensure that submission instances with a :title value of NULL are each created and not updating another previous one with the same title value?
This should do it:
ajax_title = params[:title]
ajax_content = params[:content]
ajax_folder = params[:folder_id]
ajax_parent = params[:parent_id]
ajax_children = Array(params[:children])
#submission = Submission.find_by_title(ajax_title)
if ajax_title && #submission
#submission.content = ajax_content
#submission.save
else
#submission = Submission.create(
:title=>ajax_title,
:content=>ajax_content,
:user_id=>current_user.id,
:folder_id=>ajax_folder,
:parent_id=>ajax_parent,
:children=>ajax_children,
)
end
Related
I am facing the problem when I am trying to edit & add the new data. In this controller I am creating the new data of the relatives with employee_id, if I want to change the relative when I added the wrongly using this code I can delete but unable to add. When I am adding it is saying could't find the employee with id.
Can any one tell where I am wrong?
def employee_relations
if params[:relative]
#employee = Employee.find(employee_relative_params[:employee_id])
#employee_relatives = Relative.where(employee_id: #employee.id, relation_type_id: params[:relative][:relation_type_id])
#employee_relatives = Relative.create!(employee_relative_params.merge!("created_by" => current_user.id)) if ((#employee_relatives.empty? && params[:relative][:relation_type_id] != '3') || ( params[:relative][:relation_type_id] == '3'))
else
#employee = Employee.find(params[:employee_id])
#employee_relatives = Relative.where(employee_id: params[:employee_id].to_i)
end
#relation_types= Masters::RELATION_TYPE
respond_with(#employee_relatives)
end
for removing the data: this is for deletion it will work perfectly. if
I pass the params here like
employee_relative = Relative.find_by_id(params[:employee_relation_id][:employee_id])
it is
throwing the nil value
def remove_employee_relation
employee_relative = Relative.find_by_id(params[:employee_relation_id])
employee_relative.destroy if employee_relative
#relation_types= Masters::RELATION_TYPE
respond_with({:msg => "success"}, :location => nil)
end
You do not have a value for employee_id. From your post:
Parameters: {"utf8"=>"✓", "relative"=>{"relation_type_id"=>"3", "relation_name"=>"DADsdsd", "date_of_birth"=>"", "sex"=>"Male", "status"=>"Alive", "employee_id"=>""}, "commit"=>"Save"}
So your employee id is not being set wherever you are setting it(I am assuming in your form).
In my Rails API I have the following code in my Child model:
before_create :delete_error_from_values, :check_errors, :update_child_if_exists
def delete_error_from_values
#new_error = self.values["error"]
#values = self.values.tap { |hs| hs.delete("error") }
end
def update_child_if_exists
conditions = {type: self.type, parent_id: self.parent_id}
if existing_child = Child.find_by(conditions)
new_values = existing_child.values.reverse_merge!(#values)
hash = {:values => new_values}
existing_child.update_attributes(hash)
end
end
def check_errors
if self.type == "error"
conditions = {type: self.type, parent_id: self.parent_id}
if existing_child = Child.find_by(conditions)
bd_errors = existing_child.error_summary
bd_errors[#new_error] = bd_errors[#new_error].to_i + 1
hash = {:error_summary => bd_errors}
existing_child.update_attributes(hash)
else
self.error_summary = {#new_error => 1}
end
end
end
This works like expected, except for one small detail: The Child is updated if a record by type and parent_id already exists, but it is also created. How can I refactor this to stop creation?
I've tried to include return false, but if I do this, the update is not successful.
I wish to have something like find_or_create_by, but I'm not sure how to use it for this cases.
May be you can refactor your code in following approach:
def create
#parent = Parent.find(params[:parent_id])
existing_child = Child.where(type: child_params[:type], parent_id:
child_params[:parent_id]).first
if existing_child.present?
existing_child.update_attributes(attribute: value_1)
else
#child = #parent.child.build(child_params)
end
#other saving related code goes here.
end
This is just a basic piece of example.
Try creating separate instance methods to keep the Contrller DRY. :)
I'm creating a simple upvote/downvote system similar to reddit's, where users can upvote/downvote something and change their minds if need be.
I have a page that makes an AJAX call to the 'create' action of my controller. The controller has no problem creating the record and returning the proper js.erb. However, I'd like to see if an existing post exists, and if so, I'd like to destroy it. My controller looks like this:
def create
#vote = GameVote.new
#vote.game_id = params[:game_id]
#vote.vote = params[:vote]
#vote.user_id = session[:user_id]
existing_vote = GameVote.where(whatever)
respond_to do |format|
if #vote.save
format.js
end
end
end
It just seems to ignore the middle query, preventing me from destroying it if it exists before attempting to save the new entry. Any ideas?
It seems more natural to update the existing GameVote (if one exists) instead of pair delete+create.
To do so just replace:
#vote = GameVote.new
#vote.game_id = params[:game_id]
#vote.vote = params[:vote]
#vote.user_id = session[:user_id]
existing_vote = GameVote.where(whatever)
with:
#vote = GameVote.where(game_id: params[:game_id], user_id: session[:user_id]).first_or_initialize
#vote.vote = params[:vote]
Try :
#vote = GameVote.find_or_create_by_game_id_and_user_id(params[:game_id], session[:user_id])
OR
#vote = GameVote.find_or_create(:game_id => params[:game_id], :user_id => session[:user_id])
#vote.vote = params[:vote]
I have a form to create a new Contact model.
I enter the values by hand by cutting and pasting.
Sometimes I end up adding white space on the left and right.
Here is what is in the create controller (I have a loop that checks if I have uploaded a vcard which, obviously, doesn't typically present the problem (although it could) -- but my big problem is when I type it myself.
def create
#contact = Contact.create(params[:contact])
unless #contact.vcard.path.blank?
paperclip_vcard = File.new(#contact.vcard.path)
#vcard = Vpim::Vcard.decode(paperclip_vcard).first
#contact.title = #vcard.title
#contact.email = #vcard.email
#contact.first_name = #vcard.name.given
#contact.last_name = #vcard.name.family
#contact.phone = #vcard.telephone
#contact.address.street1 = #vcard.address.street
#contact.address.city = #vcard.address.locality
#contact.address.state = #vcard.address.region
#contact.address.zip = #vcard.address.postalcode
#contact.company_name = #vcard.org.fetch(0)
end
#contact.user_id = current_user.id # makes sure every new user is assigned an ID
if #contact.save
#check if need to update company with contact info
#contact.update_company
#contact.new_todos #create the todos for the newly created contact
flash[:notice] = "Successfully created contact."
redirect_to #contact
else
render :action => 'new'
end
end
This might help: http://scottmoonen.com/2009/05/08/rails-pattern-trim-spaces-on-input/
I have a after_create method for my Contact model.
However, when I put the value, it comes out nil. How can I have a callback for a newly created model ( I do a fair amount of transformation in the create model) referenced within the callback method?
after_save :update_company
def update_company
puts self.inspect
puts self.company
if company.phone.empty?
company.phone = self.phone
company.save
end
end
When I look at the logs for self.inspect, it doesn't show any of the transformations used in the create method...yet, this should run only after it has created (and saved), the object, right?
Here is the create method:
def create
#contact = Contact.create(params[:contact])
unless #contact.vcard.path.blank?
paperclip_vcard = File.new(#contact.vcard.path)
#vcard = Vpim::Vcard.decode(paperclip_vcard).first
#contact.title = #vcard.title
#contact.email = #vcard.email
#contact.first_name = #vcard.name.given
#contact.last_name = #vcard.name.family
#contact.phone = #vcard.telephone
#contact.address.street1 = #vcard.address.street
#contact.address.city = #vcard.address.locality
#contact.address.state = #vcard.address.region
#contact.address.zip = #vcard.address.postalcode
#contact.company_name = #vcard.org.fetch(0)
end
#contact.user_id = current_user.id # makes sure every new user is assigned an ID
if #contact.save
flash[:notice] = "Successfully created contact."
redirect_to #contact
else
render :action => 'new'
end
end
Yes, this happens because you didn't use self when assigning the value to company object.
In ruby, generally you don't require the use have "self" to retrieve attributes of an instance
for example in your code. you can puts company and it would work fine.
but when assigning (on the left hand side ) you always have to use self.
so change this in your code.
self.company.phone = self.phone
company.save
or
self.company.phone = phone
company.save