I am novice to joomla. I am using Joomla 1.5. I have declared a field in database table as unique. Lets suppose , I have declared "username" as unique . I created a component named "com_user" in the administrator/components section. Now, when I add a user "xyz123", for the first time, its ok. But, during next entry, when I enter the same value, it should generate error with displaying error message showing "Username should be unique" or sth. like this . How can this be done?
The best way to do this I think is to just do a "select count(*) from..." before you try to insert the user into the database to see if the user already exists. The best way to display errors, warnings and notices would be to use the JError class
A second way is to use the getErrorNum() and getErrorMsg() methods of the DBO object.
More information on that here: http://www.joomladin.com/index.php/tutorials/34-module-development/54-exception-handling.html Although I do believe that while using this second method the user still might see a big red "Database Error: duplicate key..." message.
The store() method of your JTable class should return false when the query fails, so you could use this to determine when a duplicate record is being entered. However, the store() method will also return false when the query fails for other reasons (lost database connection, etc...).
Related
I have a form where a user enters an Id into a text field, and I then I validate said Id on the server. If the Id does not exist in the system, I display an error. I do this using async validation. If the Id does exist, however, the server will return a record from our database. I want to use those values to auto populate other fields in the form.
How would I accomplish this?
I did some searching and the closest solution I found was this other question on StackOverflow. The thing is, I want to change the value after my asycValidate logic has succeeded. I don't think I can trigger the action creator from inside asyncValidate, and I'm not aware of a way to have asyncValidate trigger a callback from inside the form component.
I was able to get it to work, by following the solutions discussed in the following thread: https://github.com/erikras/redux-form/issues/442
I have defined a many-to-many relationship between Student and Seminar models. How can I find out if one particular student is attending one particular seminar? Non-working example of what I want to achieve is illustrated below:
$seminar->students()->contains($student->id);
The following error is shown when using the above code snippet:
BadMethodCallException with message 'Call to undefined method Illuminate\Database\Query\Builder::contain()'
Try instead:
$seminar->students->contains($student->id);
Presuming $student contains an instance of the Student model you can simplify it further and just use:
$seminar->students->contains($student);
When you add parentheses you're using the Laravel query builder, and you never completed the query. To do it in the manner you had originally you would need:
$seminar->students()->get()->contains($student->id);
This method could be useful if you wanted to add constraints when fetching your students.
But generally you can omit the parentheses and a Collection will be returned, allowing you to use methods like contains.
This has the additional benefit of not re-querying the database once the relationship is loaded, so will generally be a far more efficient means of fetching relationships.
If you haven't already loaded the students and want a database efficient method of checking you could instead use:
$seminar->students()->where('students.id', $student->id)->exists();
In your case the exception is you are calling 'contains()' function (which is for Laravel Collection) on 'Query Builder'. It should be
$seminar->students->get()->contains($student->id);
but this is inefficient since this will retrieve all the students of the seminar.
so instead,
$seminar->students()->wherePivot('student_id', $student->id)->exists();
this method will check in the intermediate table of many to many relationship for particular seminar-student pair, and will return whether exists or not.
The accepted answer is wrong. $seminar->students()->exists($student->id) does not check if the relationship exists. It only checks if the student exists. The student could belong to any seminar and it would still return true.
The correct way to check if a relationship exists without fetching records from the database would be:
$seminar->students()->whereId($student->id)->exists()
Check using query
$seminar->students()->whereKey($student->getKey())->exists();
Check after query (angry), can have memory problems if you have multiple attachments
$seminar->students->contains($student->getKey());
// or
$seminar->students()->get()->contains($student->getKey());
There is custom field "Lock Flag" in Account BC, namely in S_ORG_EXT_X table. This field is made available in Opportunity BC using join to above table. The join specification is as follows: Opportunity.Account Id = Account.Id. Account Id is always populated when creating new opportunity. The requirement is that for newly created records in Opportunity BC if "Lock Flag" is equal to 'Y', then we should not allow to create the record and we should show custom error message.
My initial proposal was to use a Runtime Event that is calling Data Validation Manager business service where validation rule is evaluated and error message shown. Assuming that we have to decide whether to write record or not, the logic should be placed in PreWriteRecord event handler as long as WriteRecord have row already commited to database.
The main problem was how to determine if it is new record or updated one. We have WriteRecordNew and WriteRecordUpdated runtime events but they are fired after record is actually written so it doesn't prevent user from saving record. My next approach was to use eScript: write custom code in BusComp_PreWriteRecord server script and call BC's method IsNewRecordPending to determine if it is new record, then check the flag and show error message if needed.
But unfortunately I am faced with another problem. That joined field "Lock Flag" is not populated for newly created opportunity records. Remember we are talking about BC Opportunity and field is placed in S_ORG_EXT_X table. When we create new opportunity we pick account that it belongs to. So it reproduceable: OpportunityBC.GetFieldValue("Lock Flag") returns null for newly created record and returns correct value for the records that was saved previously. For newly created opportunities we have to re-query BC to see "Lock Flag" populated. I have found several documents including Oracle's recomendation to use PreDefaultValue property if we want to display joined field value immediately after record creation. The most suitable expression that I've found was Parent: BCName.FieldName but it is not the case, because active BO is Opportunity and Opportunity BC is the primary one.
Thanks for your patience if you read up to here and finally come my questions:
Is there any way to handle PreWrite event and determine if it is new record or not, without using eScript and BC.IsNewRecordPending method?
How to get value of joined field for newly created record especially in PreWriteRecord event handler?
It is Siebel 8.1
UPDATE: I have found an answer for the first part of my question. Now it seems so simple to me that I am wondering how I haven't done it initially. Here is the solution.
Create Runtime Event triggered on PreWriteRecord. Specify call to Data Validation Manager business service.
In DVM create a ruleset and a rule where condition is
NOT(BCHasRows("Opportunity", "Opportunity", "[Id]='"+[Id]+"'", "AllView"))
That's it. We are searching for record wth the same Row Id. If it is new record there should't be anything in database yet (remember that we are in PreWriteRecord handler) and function returns FALSE. If we are updating some row then we get TRUE. Reversing result with NOT we make DVM raise an error for new records.
As for second part of my question credits goes to #RanjithR who proposed to use PickMap to populate joined field (see below). I have checked that method and it works fine at least when you have appropriate PickMap.
We Siebel developers have used scripting to correctly determine if record is new. One non scripting way you could try is to use RuntimeEvents to set a profileattribute during the BusComp NewRecord event, then check that in the PreWrite event to see if the record is new. However, there is always a chance that user might undo a record, those scenarios are tricky.
Another option, try invokine the BC Method:IsNewRecordPending from RunTime event. I havent tried this.
For the second part of the query, I think you could easily solve your problem using a PickMap.
On Opportunity BC, when your pick Account, just add one more pickmap to pick the Locked flag from Account and set it to the corresponding field on Opportunity BC. When the user picks the Account, he will also pick the lock flag, and your script will work in PreWriteRecord.
May I suggest another solution, again, I haven't tried it.
When new records are created, the field ModificationNumber will be set to 0. Every time you modify it, the ModificationNumber will increment by 1.
Set a DataValidationManager ruleset, trigger it from PreSetFieldValue event of Account field on Opportunity BC. Check for the LockFlag = Y AND (ModificationNumber IS NULL OR ModificationNumber = 0)) and throw error. DVM should throw error when new records are created.
Again, best practices say don't use the ModNumbers. You could set a ProfileAttribute to signal NewRecord, then use that attribute in the DVM. But please remember to clear the value of ProfileAttribute in WriteRecord and UndoRecord.
Let us know how it went !
I am trying to build a form for a Happening. The Happening references a Places table by place_id.
e.g. happening "OktoberFest" has a place_id 123 which corresponds in table Places to München
These are the relationships declared in the models:
For model Place:
public function happenings()
{
return $this->hasMany('Happening');
}
For model Happening:
public function place()
{
return $this->belongsTo('Place');
}
model Happening has a place_id field linking it to Place.
I am also using {{Form::model($happening, array('route' => array('happenings.update', $happening->id)...}} as form opening
Problem 1: how to create a {{Form::text('......')}} that will be properly prefilled with München when editing the happening Oktoberfest ?
Problem 2: I was trying to get that field to work as an ajax autosuggest (i.e. starting to pull suggestions from the Places table as soon as 3 characters have been entered). I have checked a few implementations but they don't seem to mix correctly with Problem 1
To try and solve Problem 1, I have tried the solution here
Laravel 4 Form builder Custom Fields Macro
but I was unable to make it work.
Long question, it's my very first on stack overflow, please be patient :)
If a Happening is linked to Place via the column 'place_id' you have to supply an id to save in your model/table.
There are a couple of ways that I can think of:
make a list of availble Places in a radio of select, the name will be 'place_id', the value the id of the Place en something like title for the value.
instead of displaying radio's or a select a textfield with autocomplete is a great solution if you got a lot of places. I won't go into detail how to implement it but the general idea is to autocomplete the typed in placename and on selection of that place to put the id of that place in a hidden field named 'placed_id'
After saving the form save your model with the posted place_id
(and check that id if it's valid and existing, never trust user input )
my showtime table contains following fields,
id, name, showtime where id is a int type auto-increment field(pK). showtime time type unique field .
when I try to add a showtime(duplicate value) to showtime field($row->store()) it shows the following joomla error message.(I used $row->getError() method)
TableShowTime: :store failed
Duplicate entry '10:30:00' for key 'showtime' SQL=INSERT INTO `jos_myextension_showtime` (`id`,`name`) VALUES ('0','evening')
I want to know is there any way to show only the db error message without showing sql query.
I have an idea to check the duplicate values using a query before insert, is it a good practice? Plz Help.
I think that if you don't want to display the query, then you shouldn't show the other part of the error message neither (don't tell the user you're trying to insert a duplicate key). A simple fix to this might be something like this:
if ( $row>getError() ) {
echo "Could not store [...]";
}
If this is a custom component, you could also modify your table class to customize these error message, or even show distinct error messages depending on the error number.
I hope it helped!