假设我有以下ActiveRecord模型:
class Car
belongs_to :driver
end
class Driver
# Has attribute :name
has_one :car
end
Run Code Online (Sandbox Code Playgroud)
我使用这些模型定义了几个工厂:
FactoryGirl.define do
factory :car do
association :driver
trait :fast_car do
association :driver, :fast
end
end
end
FactoryGirl.define do
factory :driver do
name 'Jason'
trait :fast do
name 'Mario'
end
end
end
Run Code Online (Sandbox Code Playgroud)
当我执行以下代码时:
car = FactoryGirl.create(:car, :fast_car)
Run Code Online (Sandbox Code Playgroud)
我希望car.driver.name等于Mario,但它等于Jason。这让我相信你不能使用特征来覆盖工厂的关联。这是真的?如果是这样,覆盖Driver快速汽车的关联的正确方法是什么?
有了这个型号:
validates_presence_of :email, :message => "We need your email address"
Run Code Online (Sandbox Code Playgroud)
作为一个相当做作的例子.错误出现为:
Email We need your email address
Run Code Online (Sandbox Code Playgroud)
我如何自己提供格式?
我看了源代码,ActiveModel::Errors#full_messages它做到了这一点:
def full_messages
full_messages = []
each do |attribute, messages|
messages = Array.wrap(messages)
next if messages.empty?
if attribute == :base
messages.each {|m| full_messages << m }
else
attr_name = attribute.to_s.gsub('.', '_').humanize
attr_name = @base.class.human_attribute_name(attribute, :default => attr_name)
options = { :default => "%{attribute} %{message}", :attribute => attr_name }
messages.each do |m|
full_messages << I18n.t(:"errors.format", options.merge(:message => m))
end
end
end …Run Code Online (Sandbox Code Playgroud) 我有一个用户模型和一个帐户模型.用户拥有多个帐户,帐户属于一个用户.我已经建立了模型和协会.现在我想将其中一个帐户设为"主帐户".建立关联的最佳方式是什么?我在我的用户表中添加了一个primary_account_id列,并设置了这样的关联,但它没有用.有小费吗?
class User < ActiveRecord::Base
has_many :accounts
has_one :primary_account, :class_name => "Account"
end
class Account < ActiveRecord::Base
belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)
编辑
我看到这个问题Rails模型既有'has_one'又有'has_many',但有一些非常相似的约束,第二个答案提出了我尝试过的建议.但是当我使用它时,rails会忽略我所创建的列,并抓住表中的第一个:
>> u = User.find(1)
User Load (3.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
=> #<User id: 1, email: "XXXXXXX@gmail.com", created_at: "2012-03-15 22:34:39", updated_at: "2012-03-15 22:34:39", primary_account_id: nil>
>> u.primary_account
Account Load (0.1ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."user_id" = 1 LIMIT 1
=> #<Account id: 5, name: "XXXXXX", …Run Code Online (Sandbox Code Playgroud) 这是一个两部分问题.
第一部分,如果我正在编写验证的模型是继承自我ActiveRecord::Base需要include ActiveModel::Validations在该类中吗?铁路的API没有说,但在yehudakatz博客似乎暗示了这一点?
第二部分是放置这些验证器文件的最佳位置?在帮助者或作为新模型或在lib中?
我目前的验证器看起来像这样
class GenderValidator < ActiveModel::validator
def validate(record)
cred = /(\d{6})(\d{4})(\d{1})(\d{2})/.match(record.id_number.to_s) #breaks up the id into the relevent sections namely birthdate, gender, nationality, validator.
unless cred[0][/\d{13}/] #checks to see if the id is a valid length of numbers if it isnt then skip the validation of gender
return true
else
birthdate = cred[1] #returns a 6 digit string 'yymmdd'
parsed_gender = cred[2] #returns a 4 digit string '0001-4999:female 5000-9999:male' …Run Code Online (Sandbox Code Playgroud) 我有一种情况,我不想在我的数据库中存储验证错误的翻译密钥,而不是它自己的错误消息.想象一下以下情况:
class Car < ActiveRecord::Base
validates_presence_of :year, :fuel
end
car = Car.new(:fuel => 'Diesel')
car.save!
#=> ActiveRecord::RecordInvalid
Run Code Online (Sandbox Code Playgroud)
现在,如果我打电话:
car.errors
#=> :year=>["can't be blank"]
Run Code Online (Sandbox Code Playgroud)
我收到翻译的错误消息.
相反,我想提取生成它的翻译键(在这种情况下,我认为它会是这样的errors.messages.blank),所以我可以将它存储在我的数据库中的不同模型中,例如FailedCar我以后可以生成一个I18n自定义表单在视图中手动填写缺失的信息.
UPDATE
我认为这是这个方法,我需要挂接到.我想获取密钥和返回的选项,因此我可以在以后再次执行翻译.
我使用cancan(1.6.10)和rails 4.0.0.我有一个名为'App'(没有作用域)的模型和一个控制器Admin :: AppsController(它的作用域.即app/controllers/admin/apps_controller).
控制器代码为
class Admin::AppsController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource class: App
def index
end
#CRUD methods and some other custom methods
...
private
def app_params
params.require(:app).permit(:name, :description, :author, :url_path, :validated, :active, :version)
end
end
Run Code Online (Sandbox Code Playgroud)
我尝试创建"应用"时遇到错误.
ActiveModel::ForbiddenAttributesError - ActiveModel::ForbiddenAttributesError:
activemodel (4.0.0) lib/active_model/forbidden_attributes_protection.rb:21:in `sanitize_for_mass_assignment'
Run Code Online (Sandbox Code Playgroud)
我补充道
before_filter do
resource = controller_path.singularize.gsub('/', '_').to_sym
method = "#{resource}_params"
params[resource] &&= send(method) if respond_to?(method, true)
end
Run Code Online (Sandbox Code Playgroud)
如https://github.com/ryanb/cancan/issues/835#issuecomment-18663815中所述,但仍然出现上述错误.
我注意到Rails可能会出现多个服务器的并发问题,并希望强制我的模型始终锁定.这在Rails中是否可行,类似于强制数据完整性的唯一约束?还是只需要仔细编程?
irb(main):033:0* Vote.transaction do
irb(main):034:1* v = Vote.lock.first
irb(main):035:1> v.vote += 1
irb(main):036:1> sleep 60
irb(main):037:1> v.save
irb(main):038:1> end
Run Code Online (Sandbox Code Playgroud)
irb(main):240:0* Vote.transaction do
irb(main):241:1* v = Vote.first
irb(main):242:1> v.vote += 1
irb(main):243:1> v.save
irb(main):244:1> end
Run Code Online (Sandbox Code Playgroud)
select * from votes where id = 1;
id | vote | created_at | updated_at
----+------+----------------------------+----------------------------
1 | 0 | 2013-09-30 02:29:28.740377 | 2013-12-28 20:42:58.875973
Run Code Online (Sandbox Code Playgroud)
irb(main):040:0> v.vote
=> 1
Run Code Online (Sandbox Code Playgroud)
irb(main):245:0> v.vote
=> 1
Run Code Online (Sandbox Code Playgroud)
select * from votes where id …Run Code Online (Sandbox Code Playgroud) 假设我有两个使用 Rails 单表继承的模型。我可以轻松地在子模型中添加验证以使某些字段成为必需的。但是,如果我想要更改验证,使子模型中的字段可选或具有不同的标准(例如数字),该怎么办?
class Parent
include Mongoid::Document
field :name, type: String
field :age, type: Integer
validates :name, presence: true
validates :age, numericality: { greater_than_or_equal_to: 25 }
end
class Child < Parent
# how can I make name optional in Child?
validates :age, numericality: { less_than: 25 }
end
Run Code Online (Sandbox Code Playgroud)
我可以通过创建自定义验证方法,然后在子类中覆盖它们来完成,但我希望有一种方法可以仅使用默认的 Rails 验证器格式来做到这一点。
在 Rails 5.1 中我有以下关系:
\n\nclass RootArea < ApplicationRecord\n has_many :common_areas\nend\n\nclass CommonArea < ApplicationRecord\n belongs_to :root_area, foreign_key: \'area_id\', optional: true\nend\nRun Code Online (Sandbox Code Playgroud)\n\n以下是他们的迁移:
\n\ncreate_table "root_areas", force: :cascade do |t|\n t.integer "area_id"\n t.string "localname"\n t.string "globalname"\n t.datetime "created_at", null: false\n t.datetime "updated_at", null: false\nend\n\ncreate_table "common_areas", force: :cascade do |t|\n t.integer "area_id"\n t.string "localname"\n t.string "globalname"\n t.integer :root_area_id\n t.datetime "created_at", null: false\n t.datetime "updated_at", null: false\nend\nRun Code Online (Sandbox Code Playgroud)\n\n我的目标是“连接”common_areas到root_areas-而area_id不仅仅是id- ,以便单个根区域条目可以“拥有”多个公共区域。
例如美国(RootArea)有加利福尼亚州( …
我有以下内容:
class ModelA < ApplicationRecord
has_many :model_bs, dependent: :destroy
end
class ModelB < ApplicationRecord
belongs_to :model_a
after_destroy :action_only_if_model_a_exists
private
def action_only_if_model_a_exists
# Do things
end
end
Run Code Online (Sandbox Code Playgroud)
当我调用 时model_a.destroy,我需要能够在action_only_if_model_a_existsModelB 的回调中确定关联的 ModelA 是否仍然存在或即将被销毁。
是否有一个很好的内置 Rails 方法可以做到这一点,或者我是否需要在早期的回调中在 ModelA 中设置一个标志(例如before_destroy),然后我可以在 ModelB 的回调中检查?
编辑
我已经做了多次测试并确认在action_only_if_model_a_exists回调中执行以下操作没有帮助:
> model_a.persisted?
true
> model_a.destroyed?
false
> model_a.frozen?
false
Run Code Online (Sandbox Code Playgroud)