标签: activemodel

FactoryGirl - 覆盖与特征的关联?

假设我有以下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快速汽车的关联的正确方法是什么?

ruby-on-rails activemodel factory-bot

4
推荐指数
1
解决办法
3342
查看次数

Rails 3自定义格式化验证错误?

有了这个型号:

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)

validation ruby-on-rails activemodel

3
推荐指数
1
解决办法
5202
查看次数

模型中的多个关联

我有一个用户模型和一个帐户模型.用户拥有多个帐户,帐户属于一个用户.我已经建立了模型和协会.现在我想将其中一个帐户设为"主帐户".建立关联的最佳方式是什么?我在我的用户表中添加了一个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)

ruby-on-rails activemodel

3
推荐指数
1
解决办法
148
查看次数

Rails放置Activemodel :: validators的位置

这是一个两部分问题.

第一部分,如果我正在编写验证的模型是继承自我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)

validation ruby-on-rails activemodel

3
推荐指数
1
解决办法
1385
查看次数

如何访问ActiveModel验证错误的翻译密钥?

我有一种情况,我不想在我的数据库中存储验证错误的翻译密钥,而不是它自己的错误消息.想象一下以下情况:

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

我认为这是这个方法,我需要挂接到.我想获取密钥和返回的选项,因此我可以在以后再次执行翻译.

ruby-on-rails activemodel ruby-on-rails-3

3
推荐指数
1
解决办法
1171
查看次数

ActiveModel :: ForbiddenAttributesError + cancan + rails 4 +带有作用域控制器的模型

我使用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中所述,但仍然出现上述错误.

activemodel cancan ruby-on-rails-4

3
推荐指数
1
解决办法
3798
查看次数

如何确保模型始终使用事务和锁定(在Rails中)?

我注意到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)

DB结束

select * from votes where id …
Run Code Online (Sandbox Code Playgroud)

concurrency ruby-on-rails activemodel database-locking

3
推荐指数
1
解决办法
2009
查看次数

重写 Rails 单表继承模型中的验证

假设我有两个使用 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 验证器格式来做到这一点。

validation activemodel ruby-on-rails-4

3
推荐指数
1
解决办法
1492
查看次数

Rails 在非主键上添加外键

在 Rails 5.1 中我有以下关系:

\n\n
class RootArea < ApplicationRecord\n  has_many :common_areas\nend\n\nclass CommonArea < ApplicationRecord\n  belongs_to :root_area, foreign_key: \'area_id\', optional: true\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

以下是他们的迁移:

\n\n
create_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\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的目标是“连接”common_areasroot_areas-area_id不仅仅是id- ,以便单个根区域条目可以“拥有”多个公共区域。

\n\n

例如美国(RootArea)有加利福尼亚州( …

activerecord ruby-on-rails activemodel

3
推荐指数
1
解决办法
1842
查看次数

Rails - 检查父对象是否被销毁并且正在调用依赖对象的销毁

我有以下内容:

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)

ruby-on-rails activemodel

3
推荐指数
1
解决办法
1422
查看次数