2013-08-22 25 views
36

Đây có thể là câu hỏi ruby ​​sau đó đặt câu hỏi nhưng tôi chắc rằng tôi có thể thực hiện điều này trong ứng dụng ruby.Sửa đổi băm ruby ​​tại chỗ (thông số mạnh của đường ray)

Tôi đã xác định các thông số mạnh.

def trip_params 
    params.require(:trip).permit(:name, :date) 
end 

Bây giờ tôi nhận được các thông số đó trong một phương pháp điều khiển. Tôi muốn làm điều này.

def save 
    trip_params[:name] = 'Modifying name in place' 
    #trip_params[:name] still equals original value passed 
end 

Điều này không bao giờ hoạt động. Tên không bao giờ thay đổi. BTW: Loại trip_params là ActionController :: Tham số

Nếu tôi thực hiện một tập lệnh ruby ​​chuẩn, nó hoạt động.

test = {}  
test[:name] = "blah"  
test[:name] = "ok"  
puts test #{:name=>"ok"} 
+0

Chuyến đi có phải là bản ghi hoạt động không? Bạn có thể cần phải lưu nó một cách rõ ràng trong cơ sở dữ liệu: '@ trip.save' – Daiku

+0

Tôi lấy phần Trip.new. Đừng để điều đó làm sao lãng. Tôi đang cố gắng sửa đổi các ActionController :: Tham số băm tại chỗ. –

Trả lời

48

permit trả về một băm mới với những phím trong nó, vì vậy bạn không sửa đổi params biến thực. Bạn cũng không lưu một tham chiếu đến hàm băm trip_params trả về, do đó bạn nhận được mỗi cuộc gọi mới trong save.

Hãy thử điều này:

def save 
    tp = trip_params 
    tp[:name] = 'Modifying name in place' 
    # ... use tp later, it'll be in there 
end 

Hoặc, nếu bạn thực sự muốn nó được sử dụng theo cách mà bạn đã làm trước đó, sửa đổi trip_params như vậy:

def trip_params 
    @trip_params ||= params.require(:trip).permit(:name, :date) 
end 

Bây giờ băm được lười biếng lưu trữ và cùng một giá trị được trả lại cho các cuộc gọi trip_params tiếp theo.

+2

Điều đó có ý nghĩa ngay bây giờ! Derp. Cảm ơn sự giúp đỡ của bạn –

+3

Cuối cùng, sau nhiều giờ đấu tranh! Cảm ơn ngài. –

+1

Wow công trình của nó cho tôi !!! –

1

Điều này là do không có phương pháp như trip_params[]=(arg, val).

Ý tôi là, khi bạn gọi trip_params bạn đang trở về giá trị của params.require(:trip).permit(:name, :date), vì vậy mỗi khi bạn gọi trip_params bạn đang nhận được params một lần nữa.

Vì vậy, nếu tôi là bạn, tôi muốn xác định phương pháp trip_params như sau:

def trip_params 
    @trip_params ||= params.require(:trip).permit(:name, :date) 
end 

Và cũng sẽ xác định một phương pháp để thay đổi trip_params

def trip_params[]= (key,val) 
    trip_params # Ensure that trip_params is called once or you will get an error 
    @trip_params[key] = val 
end 

Vì vậy, bây giờ khi bạn hãy gọi trip_params bạn thực sự sẽ trả lại @trip_params và nếu @trip_params chưa được đặt thì sẽ được đặt thành params.require(:trip).permit(:name, :date)

Và sau đó khi bạn gọi trip_params[:name] = "Some name" nó sẽ đảm bảo đầu tiên mà @trip_params được khởi tạo bằng cách gọi trip_params and then it will set the :name param to "Một số tên" `

Hy vọng tôi đã giúp bạn

18

Nếu bạn thực sự muốn thay đổi params trong điều khiển bạn có thể làm điều đó trên theo cách này:

def save 
    params[:trip][:name] = 'Modifying name in place' 
    # Now trip_params[:name] is 'Modifying name in place' 
end 
+4

Tôi nghĩ đây là câu trả lời tốt nhất và đơn giản nhất ở đây. Chỉ cần sửa đổi các tham số thực tế trước, sau đó gọi phương thức tham số mạnh của bạn. Bạn thậm chí có thể làm điều đó với before_action: modify_params, chỉ [: create,: update] rồi tạo một phương thức riêng để giữ nó khỏi phương thức tạo và cập nhật của bạn. – savmac

1

Bạn cũng có thể làm

def save 
    data = trip_params.merge(name: 'new name') 
    # use data later 
end 

Nếu băm mới được hợp nhất thành một băm cũ và nếu có các khóa trùng lặp, các khóa của hàm băm mới sẽ ghi đè các khóa khớp của hàm băm cũ.

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