Rails 3 form value altered on validation error - ruby-on-rails

I am having a weird error in a Rails 3 form
I have a field called "nif" which has to comply with a rule. A "nif" is 8 numbers plus a single control letter:
class User < ActiveRecord::Base
...
validates :nif, presence: true
validate :nif_must_be_valid
...
def nif_must_be_valid
if !validate_nif self.nif
errors.add(:nif, :invalid)
end
end
end
Where validate_nif is in my application helper:
def validate_nif(value)
if value.match(/[0-9]{8}[a-z]/i)
letters = "TRWAGMYFPDXBNJZSQVHLCKE"
check = value.slice!(value.length - 1..value.length - 1).upcase
calculated_letter = letters[value.to_i % 23].chr
return check === calculated_letter
else
false
end
end
The thing is, if "nif" is invalid and I try to save the form, everything works as expected: the error appears and the wrong value is preserved. However, if the nif is correct but some other field is incorrect, when the form is reloaded the nif value (which was correct) doesn't have the final letter anymore, that is, if the value was "87613686Q" the value gets changed to "87613686". Finally, if all the form is correct (and thus gets saved) the nif is saved without the last char.
I have verified this in rails console:
user = User.new
user.nif='87613686Q'
=> "87613686Q"
user.save
(0.1ms) begin transaction
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
(0.1ms) rollback transaction
=> false
user.nif
=> "87613686"
I just don't get it. Why would the value be striped of that single last char?
My Rails version is '3.2.16', by the way.
Thanks a lot, regards
(edited#2). Added output asket by Richards (thanks)
I had to add every other required value to get the output:
user = User.new(:nombre=>'dasdsasdasso',:primer_apellido => 'sadsada',:segundo_apellido
=> 'asdsadsas', :nif => '87613686Q',:grupo_seguridad => 'sadasncia',
:categoria => 'asafrio',:telefono => '9287',:accion => 'alta')
=> #<User id: nil, accion: "alta", prioridad: nil, fecha_prevista: nil, nombre: "dasdsasdasso", primer_apellido: "sadsada", segundo_apellido: "asdsadsas", nif: "87613686Q", categoria: "asafrio", nivel: nil, telefono: "9287", movil_corporativo: nil, tarjetas_visita: nil, ubicacion: nil, grupo_seguridad: "sadasncia", carpeta_comun_unidad: nil, requiere_ordenador: nil, comentarios: nil, created_at: nil, updated_at: nil, solicitante: nil, solicitante_nombre: nil, solicitante_apellido: nil, solicitante_email: nil>
user.save!
(0.1ms) begin transaction SQL (0.3ms) INSERT INTO "users" ("accion", "carpeta_comun_unidad", "categoria", "comentarios", "created_at", "fecha_prevista", "grupo_seguridad", "movil_corporativo", "nif", "nivel", "nombre", "primer_apellido", "prioridad", "requiere_ordenador", "segundo_apellido", "solicitante", "solicitante_apellido", "solicitante_email", "solicitante_nombre", "tarjetas_visita", "telefono", "ubicacion", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["accion", "alta"], ["carpeta_comun_unidad", nil], ["categoria", "asafrio"], ["comentarios", nil], ["created_at", Thu, 13 Feb 2014 12:26:09 UTC +00:00], ["fecha_prevista", nil], ["grupo_seguridad", "sadasncia"], ["movil_corporativo", nil], ["nif", "87613686"], ["nivel", nil], ["nombre", "dasdsasdasso"], ["primer_apellido", "sadsada"], ["prioridad", nil], ["requiere_ordenador", nil], ["segundo_apellido", "asdsadsas"], ["solicitante", nil], ["solicitante_apellido", nil], ["solicitante_email", nil], ["solicitante_nombre", nil], ["tarjetas_visita", nil], ["telefono", "9287"], ["ubicacion", nil], ["updated_at", Thu, 13 Feb 2014 12:26:09 UTC +00:00]]
(6.7ms) commit transaction => true

I think the reason is in your validate_nif method.
You are using the slice method with the bang (!) which will apply the slicing directly on the variable (read more about the Bang here or here)
That's why when it takes the leter to compare with your allowed list of letters, it takes it for good (That's why the bang is also called “dangerous” method)
Try to remove that bang and see how it works !!

Related

[Amazon][JDBC](10220) Driver not capable

I am trying to update the table is redshift through Pentaho. Getting the below error message:
2016/11/24 18:15:37 - Dimension lookup/update.0 - Dimension Lookup setting preparedStatement to [SELECT cnsmr_id_KEY, Version, crm_cnsmr_id, trvs_core_cnsmr_id, cnsmr_first_name, cnsmr_last_name, cnsmr_email, contact_no, cnsmr_pswd, bus_id, primary_geo_id, cnsmr_loc_id, cnsmr_cc_handle, cnsmr_cc_desc, cnsmr_cc_expiry_date, bill_cycle_start_date, bill_cycle_end_date, registration_date, active_flag, deactivation_date, created_at, updated_at, created_by, updated_by, null, null FROM staging.trvs_consumer WHERE cnsmr_id = ? AND ? >= null
2016/11/24 18:15:37 - Dimension lookup/update.0 - AND ? < null
2016/11/24 18:15:37 - Dimension lookup/update.0 - ]
2016/11/24 18:15:38 - Dimension lookup/update.0 - Finished preparing dimension lookup statement.
2016/11/24 18:15:39 - Dimension lookup/update.0 - SQL w/ return keys=[INSERT INTO staging.trvs_consumer( Version, null, null, cnsmr_id, crm_cnsmr_id, trvs_core_cnsmr_id, cnsmr_first_name, cnsmr_last_name, cnsmr_email, contact_no, cnsmr_pswd, bus_id, primary_geo_id, cnsmr_loc_id, cnsmr_cc_handle, cnsmr_cc_desc, cnsmr_cc_expiry_date, bill_cycle_start_date, bill_cycle_end_date, registration_date, active_flag, deactivation_date, created_at, updated_at, created_by, updated_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )]
2016/11/24 18:15:39 - Dimension lookup/update.0 - ERROR (version 6.1.0.1-196, build 1 from 2016-04-07 12.08.49 by buildguy) : Because of an error this step can't continue:
2016/11/24 18:15:39 - Dimension lookup/update.0 - Unable to prepare dimension insert :
2016/11/24 18:15:39 - Dimension lookup/update.0 - INSERT INTO staging.trvs_consumer( Version, null, null, cnsmr_id, crm_cnsmr_id, trvs_core_cnsmr_id, cnsmr_first_name, cnsmr_last_name, cnsmr_email, contact_no, cnsmr_pswd, bus_id, primary_geo_id, cnsmr_loc_id, cnsmr_cc_handle, cnsmr_cc_desc, cnsmr_cc_expiry_date, bill_cycle_start_date, bill_cycle_end_date, registration_date, active_flag, deactivation_date, created_at, updated_at, created_by, updated_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
2016/11/24 18:15:39 - Dimension lookup/update.0 - [Amazon][JDBC](10220) Driver not capable.
From the pentaho forum, I came to know that its a kind of bug to generate NULL column (http://jira.pentaho.com/browse/PDI-2292)
For which I generated one empty row with surrogate key 0 and all other values NULL.
After this when I try and run the transformation, I get the below error.
2016/11/24 21:00:32 - Dimension lookup/update.0 - INSERT INTO staging.trvs_consumer( null, created_at, updated_at, cnsmr_id, crm_cnsmr_id, trvs_core_cnsmr_id, cnsmr_first_name, cnsmr_last_name, cnsmr_email, contact_no, cnsmr_pswd, bus_id, primary_geo_id, cnsmr_loc_id, cnsmr_cc_handle, cnsmr_cc_desc, cnsmr_cc_expiry_date, bill_cycle_start_date, bill_cycle_end_date, registration_date, active_flag, deactivation_date, created_at, updated_at, created_by, updated_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
2016/11/24 21:00:32 - Dimension lookup/update.0 - [Amazon][JDBC](10220) Driver not capable.
How shall I proceed ?
Pay attention to a string
2016/11/24 18:15:39 - Dimension lookup/update.0 - SQL w/ return keys=[INSERT INTO staging.trvs_consumer( Version, null, null, cnsmr_id, crm_cnsmr_id,
or in short
INSERT INTO staging.trvs_consumer( Version, null, null, cnsmr_id,
are you really want to insert into columns called null and null?
As I am using the Dimension\Lookup update, there is an option for capturing the SCD 2 type changes, where the data versioning is done in the table by the Pentaho transformation.
The error I was getting, was for the reason I was not passing values into Date From and Date until fields and hence it was being passed as Null. Null values in these fields obviously doesn't help the versioning cause and hence the error.
Please post here, if you get any further issues.

GORM trying to do insert on domain object that hasn't been updated

I have a domain class Sale that defines a hasMany = [saleComments: SaleComment]
The SaleComment domain class has a belongsTo = [sale: Sale]
When I save the Sale object inside a Service method without making any changes to the saleComment, GORM is trying to insert into the sale_comment table:
Hibernate: insert into line_item (version, amount, date_created, event_id, external_name, fee_rate, fee_rate_type, inclusive, internal_name, label, last_updated, line_item_type, org_id, parent_line_item_id, product_id, sale_id, sale_refund_id, is_tax, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into sale_comment (version, comment, date_created, last_updated, operator_id, sale_id, sale_comments_idx) values (?, ?, ?, ?, ?, ?, ?)
[2014-05-29 23:56:01,205] util.JDBCExceptionReporter Column 'sale_id' cannot be null
[2014-05-29 23:56:01,223] events.PatchedDefaultFlushEventListener Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: [com.acme.inventory.domain.SaleComment]
at com.acme.inventory.services.SaleService$_payAndCompleteSale_closure33.doCall(SaleService.groovy:1252)
at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:687)
at com.acme.inventory.services.SaleService.payAndCompleteSale(SaleService.groovy:1245)
at com.acme.inventory.controllers.SaleController.doPayAndCompleteSale(SaleController.groovy:292)
at com.acme.inventory.controllers.SaleController$_closure3_closure22.doCall(SaleController.groovy:49)
at com.acme.inventory.controllers.BaseController$_closure1.doCall(BaseController.groovy:67)
at com.acme.inventory.controllers.SaleController$_closure3.doCall(SaleController.groovy:48)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'sale_id' cannot be null
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1040)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4006)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2468)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2719)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2450)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2371)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2355)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
... 10 more
I do not understand why GORM is trying to insert a comment which hasn't been touched. Anyone have any ideas?

rails, sqlite, TypeError: can't cast Array to string

ActiveRecord::StatementInvalid in Books#index
TypeError: can't cast Array to string: INSERT INTO "amazonitems"
("asin", "author", "created_at", "detailpageurl", "isbn",
"l_image_url", "m_image_url", "manufacturer", "product_group",
"publication_date", "s_image_url", "title", "updated_at") VALUES (?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
application_helper
module ApplicationHelper
def get_amazon_item_data(asin)
rec = Amazonitem.where(asin: "#{asin}").first
if !rec or rec.updated_at < DateTime.now - 0.5
unless rec
rec = Amazonitem.new() unless rec
rec.asin = asin
end
amazon_res = Amazon::Ecs.item_lookup(asin, response_group: 'Medium')
if amazon_res and amazon_res.first_item
item = amazon_res.first_item
element = item.get_element('ItemAttributes')
rec.detailpageurl = item.get('DetailPageURL'),
rec.isbn = element.get("ISBN"),
rec.title = element.get("Title"),
rec.author = element.get_array("Author").join(","),
rec.manufacturer = element.get("Manufacturer"),
rec.product_group = element.get("ProductGroup"),
rec.publication_date = element.get("PublicationDate"),
rec.s_image_url = item.get("SmallImage/URL"),
rec.m_image_url = item.get("MediumImage/URL"),
rec.l_image_url = item.get("LargeImage/URL")
else
rec.detailpageurl = nil
end
rec.updated_at = DateTime.now
rec.save
end
return rec
end
end
I can't save into sqlite db. help me.
One of rec attributes is an array. Try adding (temporarily):
raise Hash[rec.attributes.select {|_,v| v.is_a? Array}].inspect
just before saving and correct given attributes assignment - db is expecting a string.
Also Do not touch updated_at column - it will be updated automatically.
use to_s to prevent this type of error. for example, in my application i was getting error because of this code -
Urllist.create(
:url => #abc,
:success => #success,
:failed => #failed,
:failedemail => #faillikearray
)
here #faillikearray was an array. my problem was fixed using this -
Urllist.create(
:url => #abc,
:success => #success,
:failed => #failed,
:failedemail => #faillikearray.to_s
)

Why isn't my record getting updated?

I am having issues updating a record, using save. This is my code so far
def update
if current_user.customer?
question = JobQuestion.find(job_question_params[:job_id])
question.answer = job_question_params[:answer]
# Only save, if the current user is the owner of the job.
if current_user.id == Job.find(job_question_params['job_id']).customer.id && question.save
raise JobQuestion.last.inspect
render json: { status: 201 }
end
end
end
But for some reason it doesn't get updated, this is the output from my log.
SQL (85.6ms) UPDATE "job_questions" SET "answer" = $1, "job_id" = $2, "question" = $3, "updated_at" = $4 WHERE "job_questions"."id" = 2 [["answer", "safsf"], ["job_id", 2], ["question", "test test test"], ["updated_at", Wed, 08 Jan 2014 15:04:16 UTC +00:00]]
(11.5ms) COMMIT
JobQuestion Load (0.9ms) SELECT "job_questions".* FROM "job_questions" ORDER BY "job_questions"."id" DESC LIMIT 1
Completed 500 in 218ms
RuntimeError - #<JobQuestion id: 3, job_id: 2, company_id: 2, question: "test test test", answer: nil, created_at: "2014-01-08 11:47:34", updated_at: "2014-01-08 14:17:00">:
app/controllers/api/job_questions_controller.rb:27:in `update'
actionpack (4.0.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
As you can see the raise is fetching the job question, but the answer is nil, even thought it is inserting something into it.
What am i doing wrong?
You are updating the JobQuestion with id == 2 and then fetching the one with id == 3
Try to use the same query to find the record.
JobQuestion.find(2).inspect #=> #<JobQuestion id: 2,...
JobQuestion.last.inspect #=> #<JobQuestion id: 3,...

Grails - 'in' node in Criteria query - groovy.lang.IntRange cannot be cast to java.lang.Integer

I have an Integer rankOnHighlights property in my Project domain class.
I want to query all projects that have a rankOnHighlights property between 1 and 45.
For this, I issue the following Criteria query:
Project.withCriteria {
'in' "rankOnHighlights",[1..45]
maxResults 45
order "rankOnHighlights", "desc"
}
However, I get the following error message:
groovy.lang.IntRange cannot be cast to java.lang.Integer
I have tried various different writings but to no avail.
Any suggestion is most welcome.
Thank you in advance.
I'm not sure why that doesn't work, but it should since it's similar to an example in the docs - http://grails.org/doc/latest/ref/Domain%20Classes/createCriteria.html - you should create an issue at http://jira.grails.org/browse/GRAILS
This does work however:
between "rankOnHighlights", 1, 45
Edit:
I figured out what's happening, it should be
'in' "rankOnHighlights", (1..45)
but I'd still use between since in generates bad SQL (and if the range is wide enough it can be too large for the database query parser):
...
where
this_.rank_on_highlights in (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)
...

Resources