[Resolvido] Ajuda - vRaptor - Adição List checkbox

8 respostas
Wendell_Albino

Boa tarde galera!

Sou iniciante no vRaptor e estou tentando desenvolver um sistema que possui uma tabela de usuário no banco e outra tabela com os perfis deste usuários.
Como cada usuário pode ter vários perfis diferente criei a seguinte estrutura:

Classe Usuario.java
@Entity
@Table(name = "usuario")
public class Usuario {

	@Id
	@GeneratedValue
	@Column(name = "cod_usuario")
	private Long codUsuario;

	@Column(length = 20, nullable = false, unique = true)
	private String login;

	@Column(length = 50, nullable = false)
	private String senha;

	@Column(name = "nome_usuario", length = 100, nullable = false)
	private String nomeUsuario;

	@Column(length = 150)
	private String email;

	@ManyToMany
	private Collection<Regra> regras = new ArrayList<Regra>();
// gets e sets

Classe Regra.java

@Entity
@Table(name = "regra")
public class Regra {

	@Id
	@GeneratedValue
	@Column(name = "cod_regra")
	private Long codRegra;

	@Column(length = 50, nullable = false, unique = true)
	private String perfil;
// gets e sets

No formulário de cadastro do usuário criei a seguinte estrutura para escolher os perfis do usuario:

<c:forEach items="${regras}" var="regra">
			<input type="checkbox" name="regras[]" value="${regra.codRegra}"> ${regra.perfil}
			</c:forEach>
E no controller do usuário fiz o seguinte para adicionar:
@Post
	@Path("/usuarios")
	// adicao de usuario no sistema
	public void adiciona(Usuario usuario, List<Regra> regras) {
		if (dao.existeUsuario(usuario)) {
			validator.add(new ValidationMessage("Login já existe",
					"usuario.login"));
		}
		validator.onErrorUsePageOf(UsuariosController.class).novo();

		dao.adiciona(usuario);
		result.redirectTo(UsuariosController.class).lista();
	}

Porém não está salvando as regras selecionadas no checkbox do usuário...
Alguém poderia me ajudar?

8 Respostas

Rafael_Guerreiro

Então, não está salvando porque o usuário não tem nenhuma regra “dentro” dele.

Existem 2 soluções, a bonita e a feia.
Feia:

@Post  
    @Path("/usuarios")  
    // adicao de usuario no sistema  
    public void adiciona(Usuario usuario, List&lt;Regra&gt; regras) {  
        if (dao.existeUsuario(usuario)) {  
            validator.add(new ValidationMessage("Login já existe",  
                    "usuario.login"));  
        }  
        validator.onErrorUsePageOf(UsuariosController.class).novo();  
        usuario.setRegras(regras);// Essa linha aqui seta implicitamente as regras dentro do seu usuario
        dao.adiciona(usuario);  
        result.redirectTo(UsuariosController.class).lista();  
    }

Bonita:

// JSP
&lt;c:forEach items="${regras}" var="regra"&gt;  
            &lt;input type="checkbox" name="usuario.regras" value="${regra.codRegra}"&gt; ${regra.perfil}  
            &lt;/c:forEach&gt; 
&lt;!-- //OBS: eu não tenho certeza quanto ao name, se vai os colchetes [] ou não, eu tentaria sem. Se não funcionar, coloque-os de volta. --&gt;

// Java
@Post  
    @Path("/usuarios")  
    // adicao de usuario no sistema  
    public void adiciona(Usuario usuario) {  // As regras saem daqui pois estão sendo atribuidas pelo VRaptor.
        if (dao.existeUsuario(usuario)) {  
            validator.add(new ValidationMessage("Login já existe",  
                    "usuario.login"));  
        }  
        validator.onErrorUsePageOf(UsuariosController.class).novo();  
  
        dao.adiciona(usuario);  
        result.redirectTo(UsuariosController.class).lista();  
    }
Lucas_Cavalcanti

melhorando um pouco:

<c:forEach items="${regras}" var="regra" varStatus="s">    
            <input type="checkbox" name="usuario.regras[${s.index}]" value="${regra.codRegra}"> ${regra.perfil}    
            </c:forEach>
Rafael_Guerreiro

Não é obrigatório colocar esse índice, correto?

Mas vamos supor o seguinte contexto:
Temos 10 checks, com índices de 0 à 9, mas somente os ímpares são selecionados. A lista vai ficar com “buracos”?

Naquele lá em cima é com ou sem os colchetes (ou tanto faz)?

Wendell_Albino

Rafael Guerreiro,

testei todas as formas que você disse e todas apareceram o seguinte erro:

O que será que está faltando?

Lucas_Cavalcanti

não é obrigatório, mas precisa ter pelo menos o []…

e o vraptor sabe se virar com os buracos no meio.

Lucas_Cavalcanti

muda o nome do checkbox pra:

name="usuario.regras[${s.index}].codRegra"
Rafael_Guerreiro

Esse erro diz que as Regras não estão sendo gerenciadas pelo hibernate. Então para ele, essas regras não existem no banco, ele está mandando você salvá-las no banco.

“transient” para o hibernate quer dizer algo que está fora do gerenciamento dele.

Lucas Cavalcanti:
muda o nome do checkbox pra:

name="usuario.regras[${s.index}].codRegra"


E se ele registrar um Converter para uma regra? Assim que receber o ID, faz o get no banco.
(Teoricamente assim é menos performático)

Lucas Cavalcanti:
não é obrigatório, mas precisa ter pelo menos o []…

e o vraptor sabe se virar com os buracos no meio.


Legal!

Wendell_Albino

Obrigado colegas!

Com a ajuda de vocês funcionou.

Ficou assim então:

Lista os checkbox's das regras cadastrada no banco de dados:

<c:forEach items="${regras}" var="regra" varStatus="s">      
            <input type="checkbox" name="usuario.regras[${s.index}].codRegra" value="${regra.codRegra}"> ${regra.perfil}      
            </c:forEach>

Salva os dados do formulario de cadastro de usuário, com suas regras selecionadas nos checkbox's:

@Post
	@Path("/usuarios")
	// adicao de usuario no sistema
	public void adiciona(Usuario usuario) {
		if (dao.existeUsuario(usuario)) {
			validator.add(new ValidationMessage("Login já existe",
					"usuario.login"));
		}
		validator.onErrorUsePageOf(UsuariosController.class).novo();

		dao.adiciona(usuario);
		result.redirectTo(UsuariosController.class).lista();
	}
Criado 2 de agosto de 2012
Ultima resposta 2 de ago. de 2012
Respostas 8
Participantes 3