2012-02-19 23 views
6

Tôi đang gặp sự cố trong ứng dụng Rails 3.2 của mình, trong đó thuộc tính ảo được gửi một cách an toàn qua JSON không nằm đúng vị trí trong hàm băm params. Vâng, đó không phải là nơi tôi mong đợi. Nó vẫn còn để được nhìn thấy nếu kỳ vọng của tôi là chính xác. :)Thuộc tính ảo không được chuyển sang mẫu băm bên trong các tham số

Tôi có một mô hình sử dụng các mô hình thuộc tính ảo chuẩn, như thế này:

class Track < ActiveRecord::Base 
    def rating 
    # get logic removed for brevity 
    end 

    def rating=(value) 
    # set logic 
    end 

    def as_json(options={}) # so my method is in the JSON when I use respond_with/to_json 
    super(options.merge(methods: [:rating])) 
    end 
end 

Các JSON gửi đến bộ điều khiển của tôi trông như thế này:

{"id":1,"name":"Icarus - Main Theme 2","rating":2} 

Để được rõ ràng, tên và id không phải là ảo, xếp hạng là.

tôi kết thúc với điều này trong băm params, sau khi đường ray hiện magic của nó:

{"id"=>"1", "name"=>"Icarus - Main Theme 2", "rating"=>2, "track"=>{"id"=>"1", "name"=>"Icarus - Main Theme 2"}} 

Như bạn thấy, id và tên làm cho nó vào lồng nhau: băm theo dõi, nhưng giá thì không. Đây có phải là hành vi mong đợi không? Nó phá vỡ thực tế tiêu chuẩn (phần nào) của việc sử dụng băm lồng nhau trong bộ điều khiển vì băm lồng nhau không chứa tất cả các thông số tôi cần.

Track.update(params[:id], params[:track]) # :track is missing rating 

Cảm ơn sự giúp đỡ của bạn!

+0

Bạn có thể dán biểu mẫu đang gửi, có vẻ như nó không được sắp xếp đúng theo dõi – MatthewFord

Trả lời

7

Gần đây tôi cũng đã gặp phải lỗi này. Vấn đề là, wrapper params đang xem xét mô hình Track.attribute_names của bạn để xác định cách ánh xạ dữ liệu vào một hash: track => {params}. Nếu bạn không có một mô hình liên quan, mặc định sẽ là quấn params dựa trên tên điều khiển, và bao gồm tất cả các giá trị:

class SinglesController < ApplicationController 
    def create 
    #params[:single] will contain all of your attributes as it doesn't 
    # have an activerecord model to look at. 
    @track_single = Track.new(params[:single]) 
    end 
end 

Bạn có thể gọi wrap_parameters trong bộ điều khiển của bạn để cho điều khiển hành động gì thuộc tính bao gồm khi gói của nó params của bạn, như vậy:

class TracksController < ApplicationController 
    wrap_parameters :track, :include => :rating 
    #other controller stuff below 
end 

Xem thêm ở đây: http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html

+3

Tôi gặp sự cố tương tự, khi sử dụng wrap_parameters, nếu tôi có nhiều thuộc tính không phải ảo khác, tôi phải viết tất cả chúng vào mảng bao gồm. nếu không chúng sẽ không được bao gồm trong băm yêu cầu, làm thế nào để làm điều này một cách đơn giản? vì tôi chỉ có một thuộc tính ảo mà tôi muốn đưa vào băm yêu cầu? Cảm ơn – user1883793

0

Có lẽ nếu bạn gán rating thuộc tính ảo bên trong băm lồng nhau như thế này:

def as_json(options={}) 
    super(options.merge(:track => {:methods => @rating})) 
end 

Nó sẽ cư xử theo cách mà bạn mong đợi.

0

Chỉ cần chạy qua vấn đề này và đã tìm ra một giải pháp khá tốt. Thêm dòng sau vào ApplicationController bạn

wrap_parameters exclude: [:controller, :action, :format] + ActionController::ParamsWrapper::EXCLUDE_PARAMETERS 

Bằng cách này, mọi thứ đều được gom lại dưới tài nguyên của bạn (trừ Rails thứ thêm vào băm params) và bạn sẽ không bao giờ cần phải thêm vào sau một cuộc gọi cụ điều khiển của wrap_parameters lại . : D

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