2012-10-26 37 views
5

Tôi mới dùng ruby ​​và đường ray và tôi muốn tuân thủ các tiêu chuẩn và quy ước mã hóa tốt nhất có thể, vì vậy tôi không nhận bất kỳ thói quen xấu nào. Tôi có hai mô hình: Khóa học và Vị trí. Một khóa học thuộc về một vị trí, vì một khóa học chỉ có thể có một vị trí. Một vị trí có nhiều khóa học, vì một địa điểm có thể được chia sẻ bởi nhiều khóa học.cố gắng để hiểu cách các mô hình và hiệp hội được lưu trong đường ray

Khi tạo khóa học, một vị trí có thể đã tồn tại được tìm thấy bởi ID của nó. Hoặc vị trí có thể chưa tồn tại, trong trường hợp đó, bản ghi vị trí mới phải được tạo. Trình điều khiển khóa học của tôi có hành động tạo sau đây.

def create 
    @course = Course.new(params[:course]) 

    if params[:course][:location][:id].blank? 
    @course.location = Location.create(params[:course][:location]) 
    else 
    @course.location = Location.find_by_id(params[:course][:location][:id]) 
    end 

    @course.save 

    respond_with @course 
end 

Lưu ý rằng đây là API REST chỉ phản hồi với JSON. Javascript mà làm cho các bài viết yêu cầu một mảng JSON trong các định dạng tương tự mà sẽ được trả lại bởi một yêu cầu GET

{ 
    "course": 
    { 
    "title":"US History", 
    "credits":"3", 
    "max_students":"100", 
    "location": 
    { 
     "id":"", 
     "building":"Freedom Hall", 
     "room":"301" 
    } 
    } 
} 

or 

{ 
    "course": 
    { 
    "title":"US History", 
    "credits":"3", 
    "max_students":"100", 
    "location": 
    { 
     "id":"12", # this is the only difference 
     "building":"Freedom Hall", 
     "room":"301" 
    } 
    } 
} 
  1. So với tất cả các ví dụ tôi đã đọc, mã này không giống như vậy tao nhã . Có cách nào tốt hơn để yếu tố đó?
  2. Nếu Location.create tăng ngoại lệ, @ course.save sẽ vẫn được gọi? Tôi có cần sử dụng Location.create không !?
  3. Tương tự như vậy, lỗi xác thực sẽ kết thúc trong @ course.errors mặc dù các lỗi có trên mô hình Vị trí không? Tôi có cần phải giải cứu khỏi ngoại lệ để tôi có thể trả lại lỗi cho khách hàng không?

Cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn!

Trả lời

2

Bạn có thể dọn dẹp mới bằng cách sử dụng find_or_initialize_by_id. Điều này sẽ làm việc:

def create 
    @course = Course.new(params[:course]) 
    @course.location = Location.find_or_initialize_by_id(params[:course][:location][:id], 
                 params[:course][:location]) 
    @course.save 
    respond_with @course 
end 

Về câu hỏi thứ hai của bạn, trong mã của bạn khi bạn có nó @course.save sẽ không được gọi nếu Location.create (hoặc Location.find) đặt ra một ngoại lệ (vì họ sẽ xảy ra đầu tiên). Tuy nhiên, cách tôi đã mã hóa nó ở trên, ngoại lệ sẽ xảy ra tại cùng một điểm trong mã, khi save được gọi, tại thời điểm đó hiệp hội cũng được lưu.

+0

Cảm ơn bạn! Tôi đang nghiêng về phía thứ gì đó như thế này nhưng tôi có đôi chân lạnh lẽo. Và bạn đã xác nhận những nghi ngờ của tôi về xử lý ngoại lệ - Tôi chỉ không biết liệu có bất cứ điều gì xảy ra đằng sau hậu trường có thể ảnh hưởng đến kỳ vọng của tôi hay không. Điều này có yêu cầu thêm 'accept_nested_attributes_for: location' vào mô hình Course của tôi không? – glevine

+0

Bạn được chào đón. Không AFAIK bạn không cần phải thêm 'accept_nested_attributes_for: location' để làm điều này vì bạn đang thiết lập rõ ràng các thuộc tính trên vị trí. Mặc dù, nếu bạn có thuộc tính lồng nhau, tôi tin rằng bạn có thể khởi tạo mọi thứ chỉ với '@course = Course.new (params [: course])' và thuộc tính 'location' sẽ được đặt tự động. Đã không kiểm tra rằng mặc dù vậy không chắc chắn liệu nó sẽ hoạt động khi vị trí 'id' được thiết lập. –

+0

Tôi sẽ cần phải viết một số bài kiểm tra, nhưng một khi tôi làm tôi sẽ thêm một bình luận với những phát hiện của tôi.Nỗi sợ của tôi là nếu 'id' được đặt ở vị trí lồng nhau, nhưng tất cả các trường khác đều trống, thì đường ray sẽ thực sự cập nhật các thuộc tính trên vị trí phù hợp, đặt chúng thành trống (giả sử các trường trống hợp lệ) và lưu ghi lại. Điều đó sẽ dẫn đến xóa sạch dữ liệu trong bản ghi vị trí. Nhưng tôi không thể không nghĩ rằng đường ray là đủ thông minh để biết phải làm gì. Như tôi đã nói, tôi sẽ trả lời lại khi tôi biết nó hoạt động ra sao. – glevine

1

Hãy thử điều này, trong điều khiển của bạn

def new 
    @course = Course.new 
    @location = @course.location.build # if one..many relationship 
    @location = @course.build_location # if one..one relationship 
end 

def create 
@course = Course.new(params[:course]) 
if @course.save 
    respond_with @course 
else 
    render :action => "new" 
end 
end 

thêm về nested_attributes

+0

Cảm ơn bạn đã trả lời! Lợi thế của việc này là gì, trái ngược với việc sử dụng find_or_initialize_by_id? Tôi cần tìm hiểu thêm về các mô hình lồng nhau. Tôi đoán tôi đã không kết nối các dấu chấm với điều này liên quan đến làm tổ. – glevine

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