I have an attribute which name is alias and method which create_alias.I use create_alias method as before_validation callback.In the method decleration I have following lines
while ProjectType.find_by_alias(tmp) != nil
tmp = self.alias + "-" + i.to_s
i += 1
end
As you can see, the code tries to create unique alias but on rails 4.0 we encounter this error message.
SyntaxError: /home/vagrant/.rvm/gems/ruby-1.9.3-p194#comRails4/bundler/gems/rails-39555a5b1989/activerecord/lib/active_record/dynamic_matchers.rb:65: syntax error, unexpected keyword_alias, expecting ')'
def self.find_by_alias(alias, options = {})
Change your column name. As you see, alias is Ruby keyword and it shouldn't be used as column name.
Related
I am very new at Ruby and programming and I am trying to write this simple function below
def sum_square(x=0, y, z=0)
p x**2 + y**2 + z**2
end
sum_square(2,3)
and i get this error syntax error, unexpected '=', expecting ')'
I thought i could use optional argument here
Parameters with default values should be placed after parameters without default values or, as Tom Lord stated in comments, can be "placed anywhere else in the list, so long as they are all defined together". So, if you want to keep y mandatory it should be something like
def sum_square(y, x=0, z=0)
p x**2 + y**2 + z**2
end
But it can be confusing during calls, so you can switch to named params:
def sum_square=(y, x:0, z:0)
p x**2 + y**2 + z**2
end
# all these call are valid
sum_square(1)
sum_square(1, x:2)
sum_square(1, z:2)
sum_square(1, x:2, z:3)
There are more possible ways to implement this function listed in comments with more general approach (for any number of inputs using *) or with all params being named.
A method needs to instantiate a session with various attributes, some of which are optional
session = Checkout::Session.create({
locale: I18n.locale,
reference_id: id,
customer_email: #user_mail,
[...]
})
The last shown attribute, customer_email, is optional but it should not be generated if the value does not exist.
customer_email: #user_mail unless !#user_email,
logically hits a syntax error because an additional param (the comma) is being produced
syntax error, unexpected ',', expecting end
and thus the API expects another attribute.
(customer_email: #user_mail, unless !#user_email)
also fails as there is confusion over the parenthesis
syntax error, unexpected ')', expecting then or ';' or '\n'
How should this syntax be cast?
You need to extract the options hash into a variable and manipulate it before sending it to the Checkout::Session.create.
Something like this:
options = {
locale: I18n.locale,
reference_id: id
}
options[:customer_email] = #user_mail if #user_email
session = Checkout::Session.create(options)
I have an entity: book of class Book.
The entity class has has_many relation with other tables, pages for example.
Let's say that page_1 and page_2 are valid values that I'de like to save. The non-dynamic version would be something like:
entity.pages = [page_1, page_2]
How can I set this dynamically?
I tried using send (which works fine for has_one) with no luck:
attr = :pages # my dynamic attribute
book.send(attr) = [page_1, page_2]
# SyntaxError: unexpected '=', expecting end-of-input
# mc.send(:diagnoses, '=') = [s]
# ^
When I use << it seems to work:
book.send(attr) << page_1
but the issue is that I need to support deletion, e.g. if the book had page3, and now it has page1 and page2.
I don't want to use eval, both due to performance and security. Not sure it's related, but these dynamic attributes all have the same class - has__many with a dynamic condition.
The correct format is to call the setter (assignment) method. Which is usually the attribute followed by an equal sign. In your case, you want pages=
book.send(attr.to_s + '=', [page_1, page_2] )
Equivalent to
book.send('pages=', [page_1, page_2])
which is...
book.pages=([page_1, page_2])
or more conventionally written
book.pages = [page_1, page_2]
Try book.association(:pages).target
I am trying to use where.not to replace the following:
if #friend_matches.count > 0
#court_matches = Match.available_on_courts.where('matches.id NOT IN (?)', #friend_matches.pluck(:id)).to_a
else
#court_matches = Match.available_on_courts
end
With
#court_matches = Match.available_on_courts.where.not(matches.id: #friend_matches.pluck(:id)).to_a
However I am getting the following errors.
SyntaxError: /Users/sripaladugu/Coding/matchpoint_rails/app/mailers/match_mailer.rb:8: syntax error, unexpected ':'
...on_courts.where.not(matches.id: #friend_matches.pluck(:id))....
... ^
/Users/sripaladugu/Coding/matchpoint_rails/app/mailers/match_mailer.rb:8: syntax error, unexpected ')', expecting keyword_end
...id: #friend_matches.pluck(:id)).to_a
You can provide a hash within where to specify table names as keys and column names within the second level:
#court_matches = Match.available_on_courts
.where.not(matches: { id: #friend_matches.pluck(:id) })
.to_a
I am attempting to write my own solution to a Ruby exercise from Rubymonk where the purpose is to create three methods (add, subtract, and calculate) so when 'calculate' is called you can determine whether or not numbers are added or subtracted based on what is passed in. I am receiving the following error:
main:11: syntax error, unexpected '=', expecting ')' def calculate(*numbers, options={})
Can anyone tell me what the issue is with my code? Thanks for any and all help!
def add(*numbers)
numbers.inject(0) {|sum, number| sum + number}
end
def subtract(*numbers)
numbers.inject{|diff, number| diff - number}
end
def calculate(*numbers, options={})
result = add(numbers) if options.empty?
result = add(numbers) if options[:add]
result = subtract(numbers) if options[:subtract]
result
end
def calculate(*numbers, options={})
is not a valid method definition b/c *numbers takes the place a variable number of arguments. You have two options as I see it -
def calculate(options={}, *numbers)
or
def calculate(*args)
numbers, options = args[0..-2], args[-1] || {}
if you want to keep the same argument order
The splat argument *numbers needs to be the last argument. Otherwise, how would Ruby know when to treat the last argument as options or as the last number?
You can use (*numbers, options) (without a default value), but that would require that you always pass an options hash to the method (otherwise your last number will be set as the options variable instead).
Try this way:
def calculate(options={},*numbers)
Using optional arguments after the fully optional argument ( the * notation) do not work since it creates an ambiguity.
Read more at:
http://www.skorks.com/2009/08/method-arguments-in-ruby/
You can't use both a splat and a param with a default as last argument, this is too ambiguous for the parser (how to know that the last arg passed is meant to be the options?)
you can work around this in many ways ; one idiom from rails (active support) is :
def calculate(*args)
options = args.extract_options!
# ...
end
where extract_options! is a monkey-patch to Array from ActiveSupport defined as follow :
def extract_options!
last.is_a?(::Hash) ? pop : {}
end
as a side note :
an options hash is not really usefull here. you could pass in just a symbol as first argument, maybe.
if you use a hash, logic could be simpler :
def calculate(*args)
options = args.extract_options!
method = options.fetch(:method, :add)
send method, *args
end
on add, you don't need inject(0), injectuses the first element of your array as a first "memo" value if you don't provide one
you can pass a symbol to inject, which will be the method called on your "memo" value, with "next value" as argument :
(1..10).inject(:+)
# this is the same as
(1..10).inject{ |memo, next| memo + next }
# or, more exactly
(1..10).inject{ |memo, next| memo.send :+, next }