Rizal Yusoff Rizal Yusoff - 9 days ago 4
Ruby Question

SyntaxError - syntax error, unexpected '=', expecting keyword_end when using send method Rails

i got

SyntaxError - syntax error, unexpected '=', expecting keyword_end
when I use
send
method to in order to convert the string into object in my Rails application. What's weird is that, it is working find when I am using it to compare the value to something, like this:

if @whiteboard.contract.send(user_ast_contract_accept) == true
....
end


But, when I use it to update the value, I got that error. Below is the full error:

SyntaxError - syntax error, unexpected '=', expecting keyword_end
user.send(user_credit_check) = "Submitted"
^:
app/controllers/whiteboards_controller.rb:355:in `'
activesupport (4.2.3) lib/active_support/dependencies.rb:457:in `block in load_file'
activesupport (4.2.3) lib/active_support/dependencies.rb:647:in `new_constants_in'
activesupport (4.2.3) lib/active_support/dependencies.rb:456:in `load_file'
activesupport (4.2.3) lib/active_support/dependencies.rb:354:in `require_or_load'
activesupport (4.2.3) lib/active_support/dependencies.rb:494:in `load_missing_constant'
activesupport (4.2.3) lib/active_support/dependencies.rb:184:in `const_missing'
activesupport (4.2.3) lib/active_support/inflector/methods.rb:261:in `block in constantize'
activesupport (4.2.3) lib/active_support/inflector/methods.rb:259:in `constantize'
activesupport (4.2.3) lib/active_support/dependencies.rb:566:in `get'
activesupport (4.2.3) lib/active_support/dependencies.rb:597:in `constantize'
actionpack (4.2.3) lib/action_dispatch/routing/route_set.rb:72:in `controller_reference'
actionpack (4.2.3) lib/action_dispatch/routing/route_set.rb:62:in `controller'
actionpack (4.2.3) lib/action_dispatch/routing/route_set.rb:41:in `serve'
actionpack (4.2.3) lib/action_dispatch/journey/router.rb:43:in `block in serve'
actionpack (4.2.3) lib/action_dispatch/journey/router.rb:30:in `serve'
actionpack (4.2.3) lib/action_dispatch/routing/route_set.rb:821:in `call'


Below is my codes, including the functions that i made:

def get_member_position(user, contract)
if user.id == contract.tenant1.to_i
return "tenant1"
elsif user.id == contract.tenant2.to_i
return "tenant2"
elsif user.id == contract.tenant3.to_i
return "tenant3"
elsif user.id == contract.tenant4.to_i
return "tenant4"
elsif user.id == contract.landlord.to_i
return "landlord"
elsif user.id == contract.guarantor1.to_i
return "guarantor1"
elsif user.id == contract.guarantor2.to_i
return "guarantor2"
elsif user.id == contract.guarantor3.to_i
return "guarantor3"
elsif user.id == contract.guarantor4.to_i
return "guarantor4"
else
end
end

def get_user_credit_check(user, contract)
member_position = get_member_position(user, contract)
user_credit_check = member_position + "_credit_check"

return user_credit_check
end

contract = Contract.find(params[:contract_id])
user_credit_check = get_user_credit_check(current_user, contract)
contract.send(user_credit_check) = "Submitted"
contract.save

Answer

Your code is trying to assign the string "Submitted" to the result of calling the method, ie. user.send(user_credit_check). That's not quite how it works.

If the variable user_credit_check was equal to the string "my_check", and you wanted to call user.my_check, then using send like this would work.

However, I assume you want to do something like user.my_check = "Submitted", which is actually just Ruby syntactic sugar for user.my_check=("Submitted"). So the method you want to pass to send is actually "my_check=", not "my_check", and the second argument to send is the arguments to pass, ie. "Submitted".

In summary, you want to do something like:

user.send("#{user_credit_check}=", "Submitted")

As an aside, I would always use public_send, not send for things like this - I understand that the method in this case is a Rails-provided accessor, but just in case - private methods should stay private, and this is one way of accidentally circumventing that layer of privacy.