Нужна помощь опытных программистов!

Нужна помощь опытных программистов!

Удалил

1) В контроллере нет метода, который записывает (DML insert/update) изменения в БД.
2) На странице нет вызова метода (<apex:commandButton action="{!save}" value="Save" id="theButton"/>), который должен записывать изменения в БД.

Удалил

Бро, бред написал (updatePencilBox = [UPDATE Pencil_Box__c SET Name]; ).
Читай, что такое DML операции. Как они работают в Apex.

Удалил

Опять? Хочу работать программистам а учиться не хочу?
В коде выше ВСЕ ответы на вопрос есть!
А при минимальном знании теории такого бреда даже при желании написать нельзя.

Лучше начни с теории, а не с этих "пенсилов".

Goonza,
Что б ты понимал, ты основ программирования не знаешь/понимаешь.
Не получится. Я лично пытался товарища пол года учить. Он через пол года все-равно пишет бред, который я не писал на первом курсе в колледже.
Найди курсы основ Java и их изучай. Арех после этого тебе не надо будет учить - он такой же.

Удалил

Все равно это не подход.
Это тоже самое что "я хочу написать клон facebook чтобы понять что такое web программирование".

Вот тут 2 немного устаревших, но для твоего задания очень актуальные workbooks.
https://resources.docs.salesforce.com/198/latest/en-us/sfdc/pdf/apex_workbook.pdf
https://files.meetup.com/19961651/Visualforce%20Workbook.pdf
Раньше по ним только и учились.

Тебе их надо с карандашем/ручкой/маркером пройти и сделать все задания. После этого можно что-то начинать делать свое (типа тестового задания).

Замечу сразу, то про что ты спрашиваешь для тестового задания ПОЯВЛЯЕТСЯ ТОЛЬКО В КОНЦЕ ВТОРОЙ КНИГИ. Но читать с конца нельзя!!! Надо все прочитать и заучить сначала в первой, а потом во второй.
Иначе смысла никакого от твоего желания устроиться на работу SF программистом не будет.

Вот кстати отличный пример как надо учиться чтобы стать успешным программистом.

Я когда-то в далеком 2011 году все эти воркбуки и полные документации распечатал себе на принтере (получилось под 2000 листов в сумме) и сидел днями и ночами читал, помечал и реализовывал на примерах.

Сейчас конечно это уже все бесполезная макулатура для растопки мангала, потому что свою функцию эти листы бумаги уже выполнили - перенесли информацию в мою голову.

Вот так надо учиться, а не лазить по разным сайтам пытаясь скопипастить куски кода и выдать их за свое творение.

Удалил

Подсказка
Опишите как можно подробнее, с точки зрения кода, что происходит когда вы нажимаете кнопку "Add"

Во первых разберись с понятиями get/set/update/save с точки зрения английского языка.
Почему у тебя все методы с get в названии содержат DML операцию? Одни только названия методов уже вводят в затуп.

Goonza
Подскажите пожалуйста что не так и где ,может посмотреть(прочитать), где так как надо )

Вся проблема у тебя в контроллере. Посмотреть это врядли где получится, надо включить голову и разобрать по командам что ты делаешь. Пока там бред написан, поэтому на странице у тебя тоже ничего путного не отображается.

Подсказка camamber отличнейшая! Лучше не найдешь!

Ну что?взяли вас в VRP Consulting? вроде как почти сделали тестовое задание

Большое спасибо за помощь и здравую критику (:

Интересует Ваш опытный взгляд на код, он рабочий, но с точки зрения каких-то бэст практик может есть какие-нибудь замечания или где-то, все таки, что-то работает как костыль )
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
<apex:page controller="PenBoxController">
<apex:form id="Form">
<apex:pageBlock title="Edit Page">

Enter Pen Box Name &nbsp;
<apex:inputText value="{!penBox.Name}"/> &nbsp;
<apex:commandButton action="{!savePenBox}" value="Update Name" reRender="Form"/><p/>

<apex:pageBlockTable value="{!penList}" var="item" title="Summary Table">
<apex:column value="{!item.Name}" headerValue="Pen Color"/>
<apex:column value="{!item.Pen_Box__c}" headerValue="Box Name"/>
<apex:column value="{!item.CreatedDate}" />
<apex:column value="{!item.OwnerId}" />
</apex:pageBlockTable>

</apex:pageBlock>
</apex:form>
</apex:page>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class PenBoxController {

public List<Pen__c> penList { get; set; }
public Pen_Box__c penBox { get; set; }

public PenBoxController () {
createPenTable ();
getPenBoxName ();
}

public PageReference savePenBox () {
updatePenboxToDB ();
createPenTable ();
getPenBoxName ();
return null;
}

private void createPenTable () {
penList = new List<Pen__c>();
penList = [
SELECT Id, Name, Pen_Box__c, OwnerId, CreatedDate
FROM Pen__c
ORDER BY Name ASC
];
}

private void getPenBoxName () {
penBox = new Pen_Box__c();
penBox = [
SELECT Id, Name
FROM Pen_Box__c
];
}

private void updatePenBoxToDB () {
update penBox;
}

}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
Заранее благодарен.

Позволю себе наглость сделать красиво. Для этого тут есть специальный тег code

<apex:page controller="PenBoxController">

<apex:form id="Form">
<apex:pageBlock title="Edit Page">
Enter Pen Box Name &nbsp;
<apex:inputText value="{!penBox.Name}" /> &nbsp;
<apex:commandButton action="{!savePenBox}" value="Update Name" reRender="Form" />
<p/>
<apex:pageBlockTable value="{!penList}" var="item" title="Summary Table">
<apex:column value="{!item.Name}" headerValue="Pen Color" />
<apex:column value="{!item.Pen_Box__c}" headerValue="Box Name" />
<apex:column value="{!item.CreatedDate}" />
<apex:column value="{!item.OwnerId}" />
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>

public class PenBoxController {

public List < Pen__c > penList { get;
set; }
public Pen_Box__c penBox { get;
set; }

public PenBoxController() {
createPenTable();
getPenBoxName();
}

public PageReference savePenBox() {
updatePenboxToDB();
createPenTable();
getPenBoxName();
return null;
}

private void createPenTable() {
penList = new List < Pen__c > ();
penList = [
SELECT Id, Name, Pen_Box__c, OwnerId, CreatedDate
FROM Pen__c
ORDER BY Name ASC
];
}

private void getPenBoxName() {
penBox = new Pen_Box__c();
penBox = [
SELECT Id, Name
FROM Pen_Box__c
];
}

private void updatePenBoxToDB() {
update penBox;
}

}

так же лучше выглядит?

Dmitry Shnyrev
так же лучше выглядит?

Несомненно! Вы как всегда правы)

Замечания по контроллеру

- строки 21 и 30 не имеют смысла. Следующей строкой вы все равно переписываете значение.
- не нравятся мне названия методов createPenTable и getPenBoxName. Они не отражают смысл содержимого метода. Больше подходят getPens и getPenBox.
- строки 15 и 16 тоже не имеют смысла - penBox и так уже содержит актуальное значение, а в penList ничего не поменялось.

Страница норм.

Спасибо за помощь. Я бы ещё тогда переименовал savePenBox() на updatePenBox() .

Goonza
Я бы ещё тогда переименовал savePenBox() на updatePenBox() .

Ну это уже на вкус. Эти названия не бросаются в глаза.

А, еще.
метод
private void updatePenBoxToDB() {...}
можно вообще убрать, а единственную строчку перенести в savePenBox. Не вижу в нем особого смысла.

Вот что получилось. Спасибо за подсказки!

public class PenBoxController {


public List<Pen__c> penList { get; set; }
public Pen_Box__c penBox { get; set; }

public PenBoxController () {
getPens ();
getPenBox ();
}

public PageReference updatePenBox () {
update penBox;
return null;
}

private void getPens () {
penList = [
SELECT Id, Name, Pen_Box__c, OwnerId, CreatedDate
FROM Pen__c
ORDER BY Name ASC
];
}

private void getPenBox () {
penBox = [
SELECT Id, Name
FROM Pen_Box__c
];
}

}

Ну вот! Уже красиво!

Но можно сделать еще лучше.

Во-первых в 25 строке у тебя заложена бомба замедленного действия! Попробуй просто через интерфейс создать второй Pen_Box__c (вторую запись в базе) и открой свою страницу сново.

Во-вторых два SOQL запроса (17 и 25) можно объединить в один. Погугли про вложенные запросы, но это уже выходит за рамки данного задания.

И в итоге все тестовое задание PencilBox сводится к паре строчек кода

В 25 строке - это да, Я про это уже думал ) Но по задаче нам нужно лишь 1 запись которую мы обновляем )
Про запросы погуглю обязательно, ведь нужно уметь оптимизировать код максимально!
Да, когда со знанием дела подходишь к выполнению этого задания понимаешь что оно в пару строчек и на полчаса )
Ещё раз спасибо за ценную информацию!

Для тестового задания идеально.

Если выходить за рамки и начать придираться, то:

public class PenBoxController {

желательно указывать with sharing или without sharing - т.е. если with sharing, то показываем только те записи, которые доступны пользователю по sharing модели. Если without sharing - то показываем все записи.
update penBox;
крайне желательно оборачивать в try-catch и показывать пользователю понятную ошибку, что-то вроде Update of pencil box failed. Please contact administrator. Information: %exception message%, плюс показывать stack trace ошибки.

но это уже скорее подискутировать - на такое редко обращают внимание даже опытные разработчики. Хотя, если бы писал тестовое задание, то обязательно бы сделал указанное, плюс подумал бы о query row лимитах.

Goonza
В 25 строке - это да, Я про это уже думал ) Но по задаче нам нужно лишь 1 запись которую мы обновляем )

Если нужна 1 запись, то делаем тремя ПРАВИЛЬНЫМИ способами:
- хардкодим ID в SOQL ... WHERE Id = 'my-super-puper-id'
- ставим LIMIT 1 в конце - это хотя бы убережет от того если вернутся несколько записей
- достаем в List<Pen_Box__c> и потом если лист не пустой вернулся достаем первый элемент penboxes[0] или выкидываем пользователю ошибку что не найдено.

EvAzi
показывать пользователю понятную ошибку, что-то вроде Update of pencil box failed.

Правильно! Погугли про apex:PageMessages

EvAzi
желательно указывать with sharing или without sharing - т.е. если with sharing, то показываем только те записи, которые доступны пользователю по sharing модели. Если without sharing - то показываем все записи.

А разве public class != public without sharing class?

DevNull
EvAzi
желательно указывать with sharing или without sharing - т.е. если with sharing, то показываем только те записи, которые доступны пользователю по sharing модели. Если without sharing - то показываем все записи.

А разве public class != public without sharing class?

По-моему да, но это не очевидно - правильнее указывать явно применение шеринг рулов к классу.

DevNull
А разве public class != public without sharing class?

Не совсем - всё зависит от контекста выполнения - класс задекларированый как without sharing будет всегда выполняться without sharing, а класс без указания sharing'а будет выполняться с настройками вызывающего класса. Допустим:
public class A

{
public void doA(){}
}

public without sharing B
{
public void doB(){ new A().doA(); }
}

public with sharing C
{
public void doC(){ new A().doA(); }
}

тогда возможны три варианта:

new A().doA();//method doA() will be executed without sharing

new B().doB();//method doA() will be executed without sharing
new C().doC();//method doA() will be executed with sharing

Доброго времени суток ) Небольшой вопрос...прохожу Trailhead и немного застрял. Вот задание :

Create an Apex class that returns Account objects.

To pass this challenge, create an Apex class that returns a List of Account objects for a user-specified state.

-Create an Apex class named AccountUtils and include a static method named accountsByState that accepts a state abbreviation as a string and returns a List of Account objects
-The method must return the ID and name of all Account objects that match the BillingState for the state abbreviation passed to the method

Вот что у меня получилось:

public class AccountUtils {

public static String [] toBillingStates {get; set;}
public static List <Account> acc {get; set;}

public static void accountsByState (String BillingState) {
toBillingStates = new String [] {BillingState};
acc = new List <Account> ();
acc = [SELECT Id, Name FROM Account WHERE BillingState= :toBillingStates];
System.debug(acc);
}

}

И Trailhead пишет ошибку(хотя когда проверяю в Execute Anonymous Window и пишу AccountUtils.accountsByState ('IL'); выводит всё верно) :

Challenge not yet complete in My Trailhead Playground 1

Executing the 'accountsByState' method on 'AccountUtils' failed. Make sure there are no required fields other than Name for the Account object, the method exists with the name 'accountsByState', is public and static, accepts a String and returns a List of Account objects.

Заранее благодарен!

а метод то у тебя войдовый! а что должен вернуть?

Den Brown
а метод то у тебя войдовый! а что должен вернуть?

Спасибо за помощь! Встал с утра и понял ошибку) В 3 часа ночи как то голова затуманилась, очевидные вещи не заметил)

Goonza
Create an Apex class that returns Account objects.
To pass this challenge, create an Apex class that returns a List of Account objects for a user-specified state.

Блин, вот даже задание само звучит как бред. Как класс что-то может вернуть??? Вернуть может метод внутри класса. Нафига такое писать? (вопрос не к автору вопроса, а к создателям этого урока в Trailhead)

Вот на свежую голову исправил )

public class AccountUtils {

public static String [] toBillingStates {get; set;}
public static List <Account> acc {get; set;}

public static List<Account> accountsByState (String BillingState) {
toBillingStates = new String [] {BillingState};
acc = new List <Account> ();
acc = [SELECT Id, Name FROM Account WHERE BillingState= :toBillingStates];
System.debug(acc);
return acc;
}

}

Зачем выносить переменные toBillingStates и acc из метода?

Видимо не зачем - если Вы спрашиваете )Я их просто сразу вынес, думал что-то грандиозное напишу , а нет )

Интересная информация? Помогите сайту, разместите ссылку в социальных сетях..