2010-05-25 26 views
11

Tôi mới dùng grails và cố tạo biểu mẫu cho phép người dùng thay đổi địa chỉ email được liên kết với tài khoản của họ cho trang web tôi đang tạo.Grails, làm cách nào để tôi nhận được một đối tượng KHÔNG được lưu

Nó yêu cầu người dùng nhập mật khẩu hiện tại của họ và cũng cho địa chỉ email mới mà họ muốn sử dụng. Nếu người dùng nhập sai mật khẩu hoặc địa chỉ email không hợp lệ thì nó sẽ từ chối chúng với một thông báo lỗi thích hợp.

Bây giờ xác thực email có thể được thực hiện thông qua các ràng buộc trong grails, nhưng thay đổi mật khẩu phải khớp với mật khẩu hiện tại của chúng. Tôi đã thực hiện kiểm tra này như một phương thức trên một lớp dịch vụ.

Xem mã bên dưới:

def saveEmail = 
{ 
    def client = ClientUser.get(session.clientUserID) 
    client.email = params.email 
    if(clientUserService.checkPassword(session.clientUserID , params.password) ==false) 
    { 
     flash.message = "Incorrect Password" 
     client.discard() 
     redirect(action:'changeEmail') 
    }  
    else if(!client.validate()) 
    { 
     flash.message = "Invalid Email Address" 
     redirect(action:'changeEmail') 
    } 
    else 
    { 
     client.save(); 
     session.clientUserID = null; 
     flash.message = "Your email address has been changed, please login again" 
     redirect(controller: 'clientLogin' , action:'index') 
    } 
} 

Bây giờ những gì tôi nhận thấy đó là lẻ là nếu tôi bước vào một email không hợp lệ thì nó sẽ không lưu các thay đổi (như mong đợi) NHƯNG nếu tôi nhập sai mật khẩu và một email hợp lệ sau đó nó sẽ lưu các thay đổi và thậm chí ghi chúng trở lại vào cơ sở dữ liệu ngay cả khi nó sẽ cung cấp thông báo lỗi "mật khẩu không hợp lệ" chính xác.

Tôi đã bối rối nên đặt điểm ngắt trong tất cả if/else if/else chặn và thấy rằng nó đã nhấn vào câu lệnh if đầu tiên như dự kiến ​​và không đánh người khác, vì vậy nó sẽ không bao giờ đi qua một cuộc gọi để lưu() phương pháp, nhưng nó đã được lưu anyway.

Sau một ít nghiên cứu, tôi đã xem xét tài liệu về phương thức discard() mà bạn có thể thấy được sử dụng trong mã ở trên. Vì vậy, tôi đã thêm điều này nhưng vẫn không có kết quả. Tôi thậm chí đã thử sử dụng loại bỏ sau đó tải lại đối tượng khách hàng từ DB một lần nữa nhưng vẫn không có con xúc xắc.

Điều này rất bực bội và tôi sẽ biết ơn vì sự giúp đỡ nào, vì tôi nghĩ rằng điều này chắc chắn không phải là một yêu cầu phức tạp!

+0

client.discard() phải là cách để làm điều đó, bạn có thể tái tạo sự cố trong thử nghiệm tích hợp không? Bạn đang sử dụng phiên bản Grails nào? – leebutts

+0

Tôi vừa thử một bài kiểm tra tích hợp trên mã, kỳ quặc đủ nó dường như cư xử như tôi muốn nhưng khi tôi đã làm nó bình thường thông qua các trang web tôi đã nhận được cùng một vấn đề một lần nữa. Tôi muốn đăng mã thử nghiệm nhưng tôi không thể tìm ra cách để làm điều đó ở đây, nó cho tôi biết rằng có quá nhiều ký tự – user350325

+0

bạn nên chấp nhận câu trả lời dưới đây! – oligofren

Trả lời

10

Grails đóng phiên Hibernate của bạn ở cuối yêu cầu web, thao tác này sẽ xóa đối tượng đã thay đổi. Đối tượng được kết nối với phiên Hibernate của bạn vì bạn đã giữ nó thông qua Hibernate (get()). Nếu bạn muốn tránh bị thay đổi, bạn cần sử dụng discard().

Điều này được thực hiện tự động bởi trình xác thực không thành công, đó là lý do tại sao bạn không phải thực hiện việc xác thực không thành công. Tuy nhiên, bạn sẽ đơn giản hóa mã này bằng cách di chuyển logic này đến trình xác thực tùy chỉnh trên một trong các trường ClientUser của bạn, thao tác này sẽ tự động hủy đối tượng khi không thành công hoặc bằng cách sử dụng đối tượng lệnh Grails, cũng có thể đóng gói logic xác minh. Sau đó, bạn chỉ cần kiểm tra lỗi trên đối tượng lệnh.

+0

vâng, nhưng đó là điều làm tôi bối rối, tôi đang sử dụng loại bỏ và điều này đang làm việc trên thử nghiệm tích hợp nhưng không phải trên web – user350325

+1

Hãy nhớ rằng, các thử nghiệm tích hợp sẽ phục hồi giao dịch của bạn ở cuối. Tại trang web, giao dịch của bạn cuối cùng sẽ được thực hiện. –

0

Bạn chỉ đang thực hiện flash mà không có gì liên quan đến việc quay lại giao dịch. Trong trường hợp lỗi ném RuntimeException và nó sẽ quay trở lại những thay đổi của bạn vào cơ sở dữ liệu.

2

Sử dụng phương pháp read truy xuất phiên bản của lớp tên miền cho id được chỉ định ở trạng thái chỉ đọc.

Xem Grails documentation about read.

5

Sử dụng phương thức get() để truy xuất dữ liệu ở chế độ đọc-ghi, vì vậy nếu bạn thay đổi bất cứ điều gì nó sẽ tồn tại. Sử dụng phương thức read() có thể lấy dữ liệu ở chế độ chỉ đọc, nếu bạn thay đổi bất cứ thứ gì thì cần sử dụng save() method.That sẽ giải quyết vấn đề của bạn.

Hãy xem này http://grails.org/doc/latest/guide/GORM.html#basicCRUD

+0

điều này làm việc cho tôi mặc dù tôi không hiểu tại sao loại bỏ không hoạt động nếu bạn sử dụng nhận được, cảm ơn anyway – sttaq

0

Sau một R & D, tôi hình dung ra rằng chúng ta cần phải rõ ràng một phiên toàn như:

session.clear() 

Theo documentation:

Hoàn toàn xóa phiên. Hủy bỏ tất cả các trường hợp đã tải và hủy tất cả các lần lưu, cập nhật và xóa đang chờ xử lý. Không đóng các trình vòng lặp mở hoặc các phiên bản của ScrollableResults.

Chúng tôi cần dọn dẹp phiên ngủ đông đúng cách. Kết quả là phiên trở về trạng thái có thể sử dụng và để sử dụng trong tương lai, phiên sẽ không ảnh hưởng bởi lỗi trước đó.

Các vấn đề liên quan