gpt4 book ai didi

ruby-on-rails - Rails 4 中的 ForbiddenAttributesError

转载 作者:数据小太阳 更新时间:2023-10-29 06:41:13 25 4
gpt4 key购买 nike

我正致力于将遗留应用程序升级到 Rails 4,但我遇到了无法解释的(至少对我而言)ForbiddenAttributesError

在使用它们创建 Station 的新实例之前,我已经将参数列入白名单,但出于某种原因我仍然得到ForbiddenAttributesError。有什么方法可以获取有关导致错误的属性的更多信息吗?


** 编辑。我正在使用 Devise 和 CanCan。如果我删除 load_and_authorize_resource,错误就会消失(授权也一样!)。我已经尝试了 https://github.com/ryanb/cancan/issues/835 上的解决方案没有用。


rspec 规范/controllers/stations_controller_spec.rb

  1) StationsController POST 'create' invalid should not create a new record
Failure/Error: post :create, :station => { :name => 'foo' }
ActiveModel::ForbiddenAttributesError:
ActiveModel::ForbiddenAttributesError
# ./spec/controllers/stations_controller_spec.rb:67:in `block (5 levels) in <top (required)>'
# ./spec/controllers/stations_controller_spec.rb:66:in `block (4 levels) in <top (required)>'

2) StationsController POST 'create' valid should create a new record
Failure/Error: before { post :create, :station => FactoryGirl.attributes_for(:station, :hw_id => rand(1000)) }
ActiveModel::ForbiddenAttributesError:
ActiveModel::ForbiddenAttributesError
# ./spec/controllers/stations_controller_spec.rb:73:in `block (4 levels) in <top (required)>'

3) StationsController POST 'create' valid
Failure/Error: before { post :create, :station => FactoryGirl.attributes_for(:station, :hw_id => rand(1000)) }
ActiveModel::ForbiddenAttributesError:
ActiveModel::ForbiddenAttributesError
# ./spec/controllers/stations_controller_spec.rb:73:in `block (4 levels) in <top (required)>'

架构.rb

  create_table "stations", :force => true do |t|
t.string "name"
t.string "hw_id"
t.float "lat"
t.float "lon"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "timezone"
t.float "balance"
t.integer "user_id"
t.boolean "down"
end

station_controller.rb

      ...
# POST /stations
# POST /stations.xml
def create
@station = Station.new(station_params)
@station.set_timezone!
logger.debug("@station " + @station.inspect)
respond_to do |format|
if @station.save
format.html { redirect_to(@station, :notice => 'Station was successfully created.') }
format.xml { render :xml => @station, :status => :created, :location => @station }
format.yaml { render :status => :ok, :nothing => true }
else
# create users list if the station cannot be created
@users = User.all_users_select(current_user)
format.html { render :action => "new" }
format.xml { render :xml => @station.errors, :status => :unprocessable_entity }
format.yaml { render :status => :unprocessable_entity, :nothing => true }
end
end
end

...

# whitelists params for mass assignment
def station_params
params.require(:station).permit(
:user_id, :name, :hw_id, :measures, :lat, :lon, :authenticity_token, :commit
)
end

station_controller_spec.rb

      describe "POST 'create'" do
describe "invalid" do
it "should not create a new record" do
expect do
post :create, :station => { :name => 'foo' }
end.to_not change(Station, :count)
end
end

describe "valid" do
before { post :create, :station => FactoryGirl.attributes_for(:station, :hw_id => rand(1000)) }
it "should create a new record" do
expect do
post :create, :station => FactoryGirl.attributes_for(:station, :hw_id => rand(1000))
end.to change(Station, :count)
end
subject { response }
it { should redirect_to station_path(assigns(:station)) }
end
end

工厂/station.rb

    FactoryGirl.define do
factory :station do
name "Test Staton"
hw_id Time.now.to_s
lat 63.401839
lon 13.072183
end
factory :invalid_station, class: Station do
name nil
end
end

模型/station.rb

#include Geokit::Geocoders
class Station < ActiveRecord::Base
#acts_as_mappable :default_units => :kms,
# :lat_column_name => :lat,
# :lng_column_name => :lon
belongs_to :user
has_many :measures, :dependent => :destroy
has_one :current_measure, :class_name => "Measure"

# arduino client has not memory enough to post the station name so it cannot be required!
validates :hw_id, :presence => true # must have a hw_id
validates :hw_id, :uniqueness => true # and the hw_id must be unique

# Geocoder gem attribute mapping
geocoded_by :name, :latitude => :lat, :longitude => :lon

def owned_by?(owner)
user==owner
end

def calibrate_speed(speed)
speed/250
end

def self.send_low_balance_alerts
stations = Station.find(:all)
stations.each do |station|
logger.info "Checking station #{station.name}"
logger.info "Last measure at #{station.current_measure.created_at}"
if station.balance/100 < 15 && !station.down
if !station.user.nil?
logger.info "Send reminder to owner #{station.user}"
UserMailer.notify_about_low_balance(station.user, station).deliver
end
end
end
end

def self.send_down_alerts
stations = Station.find(:all)
stations.each do |station|
logger.info "Checking station #{station.name}"
logger.info "Last measure at #{station.current_measure.created_at}"
if station.current_measure.created_at < 15.minutes.ago && !station.down
station.down = true
station.save
if !station.user.nil?
logger.info "Send reminder to owner #{station.user}"
UserMailer.notify_about_station_down(station.user, station).deliver
end
end
end
end

def self.get_timezone(lat, lon)
timezone = Timezone::Zone.new :latlon => [lat, lon]
timezone.active_support_time_zone
end



def set_timezone!
if (!self.lat.nil? && !self.lon.nil?)
self.timezone = Station.get_timezone(self.lat, self.lon)
end
end

end

最佳答案

这完全是 CanCan 与 Rails 4 不兼容的问题,与我的 Station 模型或 Controller 无关。
我的解决方法是为 create 操作skip_load_resource

before_filter :authenticate_user!, :except => [:show, :index]
load_and_authorize_resource :except => [:show, :index]
skip_load_resource :only => [:create]

砰!一切都变绿了。

更新。查看CanCanCan它是现已过时的康康舞的延续,并具有 Rails 4 强大的参数支持等功能。

关于ruby-on-rails - Rails 4 中的 ForbiddenAttributesError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19856112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com