- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个模型 Foo,它有 state_code
作为外键。 States 表是一个(或多或少)静态表,用于保存 50 个州的代码和名称,以及其他美国邮政编码(例如波多黎各的“PR”)。我选择使用 state_code
作为状态的主键和 Foo 的外键,而不是像 state_id
这样的东西.它更适合人类阅读,并简化了我想要调用状态代码的 View 逻辑。 ( 编辑 - 只是为了澄清:我不是说调用代码从 View 访问模型;我的意思是将状态显示为 @foo.state_code
似乎比 @foo.state.state_code
更简单。)
Foo 还有一个 has_many
与模型 Bar 的关系。两个模型规范都通过了有效工厂的规范,但是由于某种原因,在运行构建 Bar 实例的功能规范时,由于与 state_code
相关的外键问题,测试失败了。
我的所有模型都通过了模型规范,包括对有效工厂的测试。但是,每当我尝试为“Bar”创建测试对象时,都会遇到麻烦。使用 build
因 state_code
的外键错误而崩溃在 Foo 中(尽管 Foo 工厂明确指定了一个值,该值被确认为在 States 中作为 state_code 存在)。使用 build_stubbed
因为 Bar 对象似乎没有持久化该对象。
型号:
# models/foo.rb
class Foo < ActiveRecord
belongs_to :state, foreign_key: 'state_code', primary_key: 'state_code'
has_many :bars
validates :state_code, presence: true, length: { is: 2 }
# other code omitted...
end
# models/state.rb
class State < ActiveRecord
self.primary_key = 'state_code'
has_many :foos, foreign_key: 'state_code'
validates :state_code, presence: true, uniqueness: true, length: { is: 2 }
# other code omitted...
end
# models/bar.rb
class Bar < ActiveRecord
belongs_to :foo
# other code omitted
end
# spec/factores/foo_bar_factory.rb
require 'faker'
require 'date'
FactoryGirl.define do
factory :foo do
name { Faker::Company.name }
city { Faker::Address.city }
website { Faker::Internet.url }
state_code { 'AZ' } # Set code for Arizona b/c doesn't matter which state
end
factory :bar do
name { Faker::Name.name }
website_url { Faker::Internet.url }
# other columns omitted
association :foo
end
end
# spec/models/foo_spec.rb
require 'rails_helper'
describe Foo, type: :model do
let(:foo) { build(:foo) }
it "has a valid factory" do
expect(foo).to be_valid
end
# code omitted...
end
# spec/models/bar_spec.rb
require 'rails_helper'
describe Bar, type: :model do
let(:bar) { build_stubbed(:bar) } # have to build_stubbed - build causes error
it "has a valid factory" do
expect(bar).to be_valid
end
end
build(:bar)
用于 Bar 而不是
build_stubbed
,我收到外键错误:
1) Bar has a valid factory
Failure/Error: let(:bar) { build(:bar) }
ActiveRecord::InvalidForeignKey:
PG::ForeignKeyViolation: ERROR: insert or update on table "bars" violates foreign key constraint "fk_rails_3dd3a7c4c3"
DETAIL: Key (state_code)=(AZ) is not present in table "states".
feature "Bar pages" do
context "when signed in as admin" do
let!(:bar_1) { build_stubbed(:bar) }
let!(:bar_2) { build_stubbed(:bar) }
let!(:bar_3) { build_stubbed(:bar) }
# code omitted...
scenario "clicking manage bar link shows all bars" do
visit root_path
click_link "Manage bars"
save_and_open_page
expect(page).to have_css("tr td a", text: bar_1.name)
expect(page).to have_css("tr td a", text: bar_2.name)
expect(page).to have_css("tr td a", text: bar_3.name)
end
end
save_and_open_page
不在 View 中显示预期的项目。 (不过,我有一个包含开发数据的工作页面,所以我知道该逻辑实际上按预期工作)。
The thoughtbot post on build_stubbed
表示它应该持久化对象:
It makes objects look look like they’ve been persisted, creates associations with the build_stubbed strategy (whereas build still uses create), and stubs out a handful of methods that interact with the database and raises if you call them.
build
代替
build_stubbed
在此规范中生成与上述相同的外键错误。
build_stubbed
View 之间的对象。感觉一团糟,但我想不出正确的方法来解决它。我在实践中有实际的工作 View ,可以满足我的期望 - 但我希望测试覆盖率有效。
state_code
的自然键。 .我遵循了@Max 的所有建议。 Foo 表现在使用
state_id
作为
states
的外键;我复制了
app/models/concerns/belongs_to_state.rb
的代码如推荐等。
create_table "foos", force: :cascade do |t|
# columns omitted
t.integer "state_id"
end
create_table "states", force: :cascade do |t|
t.string "code", null: false
t.string "name"
end
add_foreign_key "foos", "states"
:code
上的唯一性约束而失败。
Failure/Error: let!(:foo_2) { create(:foo) }
ActiveRecord::RecordInvalid:
Validation failed: Code has already been taken
:state_id
列直接在工厂中用于 :foo 以避免调用 :state 工厂。例如。
# in factory for foo:
state_id { 1 }
# generates following error on run:
Failure/Error: let!(:foo_1) { create(:foo) }
ActiveRecord::InvalidForeignKey:
PG::ForeignKeyViolation: ERROR: insert or update on table "foos" violates foreign key constraint "fk_rails_5f3d3f12c3"
DETAIL: Key (state_id)=(1) is not present in table "states".
state_id
不在州,因为它是
id
状态,和
state_id
在福斯。另一种方法:
# in factory for foo:
state { 1 } # alternately w/ same error -> state 1
ActiveRecord::AssociationTypeMismatch:
State(#70175500844280) expected, got Fixnum(#70175483679340)
# in factory for foo:
state { State.first }
ActiveRecord::RecordInvalid:
Validation failed: State can't be blank
states
中的状态之一的关系。 table 。我预计不会对
states
进行大量更改表 - 这真的只是一个引用。
state_id
在具有
:id
中的 66 个值之一的 Foo 对象上状态表上的列。从概念上讲,工厂为
:foo
理想情况下,为
:state_id
选择一个 1 到 66 之间的整数值.它在控制台中工作:
irb(main):001:0> s = Foo.new(name: "Test", state_id: 1)
=> #<Foo id: nil, name: "Test", city: nil, created_at: nil, updated_at: nil, zip_code: nil, state_id: 1>
irb(main):002:0> s.valid?
State Load (0.6ms) SELECT "states".* FROM "states" WHERE "states"."id" = $1 LIMIT 1 [["id", 1]]
State Exists (0.8ms) SELECT 1 AS one FROM "states" WHERE ("states"."code" = 'AL' AND "states"."id" != 1) LIMIT 1
=> true
:code
上的唯一性约束。栏目
states
.或者 - 删除
foos
之间的外键约束和
states
,并让 Rails 强制执行这种关系。
最佳答案
我将在 *rse 中感到痛苦,并认为约定可能比开发人员的便利性和感知的可读性更重要。
Rails 的一大优点是强大的约定允许我们打开任何项目并很快弄清楚发生了什么(假设原作者不是完全黑客)。用 PHP 项目试试。
这些约定之一是外键后缀 _id
.许多其他组件(例如 FactoryGirl)依赖于这些约定。
我还认为,如果您的应用在美国以外的地区使用,使用州代码作为主要 ID 会导致问题。当您需要跟踪加拿大各省或印度各州和领地时会发生什么?你将如何处理不可避免的冲突?即使您认为这可能不是今天的交易,请记住,需求会随着时间而变化。
我将其建模为:
create_table "countries", force: :cascade do |t|
t.string "code", null: false # ISO 3166-1 alpha-2 or alpha-3
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "countries", ["code"], name: "index_countries_on_code"
create_table "states", force: :cascade do |t|
t.integer "country_id"
t.string "code", null: false
t.string "name", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "states", ["code"], name: "index_states_on_code"
add_index "states", ["country_id", "code"], name: "index_states_on_country_id_and_code"
add_index "states", ["country_id"], name: "index_states_on_country_id"
"and simplifies view logic where I want to call the state code"
State.find_by(code: 'AZ')
而不是
State.find('AZ')
很可能没有你想象的那么重要。
class State < ActiveRecord::Base
# Only the State model should be validating its attributes.
# You have a major violation of concerns.
validates_uniqueness_of :state_code
validates_length_of :state_code, is: 2
end
# app/models/concerns/belongs_to_state.rb
module BelongsToState
extend ActiveSupport::Concern
included do
belongs_to :state
validates :state, presence: true
validates_associated :state # will not let you save a Foo or Bar if the state is invalid.
end
def state_code
state.state_code
end
def state_code= code
self.assign_attributes(state: State.find_by!(state_code: code))
end
end
class Foo < ActiveRecord::Base
include BelongsToState
end
class Bar < ActiveRecord::Base
include BelongsToState
end
# spec/factories/foos.rb
require 'faker'
FactoryGirl.define do
factory :foo do
name { Faker::Company.name }
city { Faker::Address.city }
website { Faker::Internet.url }
state
end
end
# spec/factories/states.rb
FactoryGirl.define do
factory :state do
state_code "AZ"
name "Arizona"
end
end
shoulda-matchers
对于极其简洁的验证示例:
require 'rails_helper'
RSpec.describe Foo, type: :model do
let(:foo) { build(:foo) }
it { should validate_presence_of :state }
it 'validates the associated state' do
foo.state.state_code = 'XYZ'
foo.valid?
expect(foo.errors).to have_key :state
end
describe '#state_code' do
it 'returns the state code' do
expect(foo.state_code).to eq 'AZ'
end
end
describe '#state_code=' do
let!(:vt) { State.create(state_code: 'VT') }
it 'allows you to set the state with a string' do
foo.state_code = 'VT'
expect(foo.state).to eq vt
end
end
end
# spec/models/state_spec.rb
require 'rails_helper'
RSpec.describe State, type: :model do
it { should validate_length_of(:state_code).is_equal_to(2) }
it { should validate_uniqueness_of(:state_code) }
end
FactoryGirl.create
不是
build_stubbed
.
build_stubbed
不会将模型持久化到数据库中,在这些情况下,您需要 Controller 能够从数据库加载记录。
CSS
如果可能,请在您的功能规范中使用选择器。功能规范应该从用户的 POV 描述您的应用程序。
feature "Bar management" do
context "as an Admin" do
let!(:bars){ 3.times.map { create(:bar) } }
background do
visit root_path
click_link "Manage bars"
end
scenario "I should see all the bars on the management page" do
# just testing a sampling is usually good enough
expect(page).to have_link bars.first.name
expect(page).to have_link bars.last.name
end
scenario "I should be able to edit a Bar" do
click_link bars.first.name
fill_in('Name', with: 'Moe´s tavern')
# ...
end
end
end
关于ruby-on-rails - 由于模型中的外键,FactoryGirl 炸毁了规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31773581/
sanitize 是什么意思在 Rails 中是什么意思? 我正在阅读 CanCanCan 的文档.它说: When using strong_parameters or Rails 4+, you
在过去的几个月里,我感觉自己对 Ruby on Rails (RoR) 开发的了解达到了极限。我为大/小客户和 friend /爱好项目开发了大大小小的应用程序。我知道如何开发这些应用程序,但开始感觉
我昨天参加了一个关于扩展 Rails 的聚会,其中一个主题是 Hexagonal Rails。然而,我只做了一年的 Rails,对 MVC 结构非常满意(也许太舒服了),所以我不太了解适配器和消息队列
我使用多个 Rails 应用程序,一些在 Rails 3.2/Ruby 2.0 上,一些在 Rails 2.3/Ruby 1.8.7 上。 他们的共同点是,随着他们的成长和添加更多的依赖项/ gem
这个问题在这里已经有了答案: Using Rails-UJS in JS modules (Rails 6 with webpacker) (5 个答案) 关闭 3 年前。 我正在尝试使用 UJS
我正在开发一个当前使用 Rails 1.2 的 Rails 应用程序,所以我现在离最新的稳定版本(Rails 2.3)还有很长的路要走。 我应该如何进行迁移到更新版本的 Rails 的过程? 我应该一
尝试按照 Ryan Bates Backbone.js 教程构建抽奖应用程序,但我已经遇到了第一段代码的问题。在 application.js 的 init 函数中,他初始化了 Raffler 路由的
我正在使用 Rails 3.2 并且我有一个数据库表,我想在其中找到符合以下条件的所有行: a = true and b = true and ( 0 true, :b =>
我有一个用户类和一个联系人,其中联系人是用户的子类。这两个类都存储在用户表中。 我的联系人可能有也可能没有电子邮件地址,而我的用户需要一个电子邮件地址(我的用户模型定义中有 validates_pre
我正在编写一个教程,我在其中演示了一些 rails 命令。在我的机器上 rails和 script/rails两者都同样有效。有“首选”形式吗?两者中哪一个更普遍? 最佳答案 当您运行 rails 时
我正在寻找有关通过我的应用程序前进的最佳方式的建议,这是我首次开始集成Elasticsearch。我是一名初学者,但是热衷于深入研究,以便原谅任何明显的错误! 我遵循了http://www.sitep
我刚刚用 Rails new 启动了一个新的 Rails 应用程序,将默认数据库设置更改为 PostgresSQL。我用 bin/rails s 启动服务器,结果很奇怪 2016-04-21 05:0
我收到一个参数并希望它是这样的字符串: "abc,efg" 或者像这样的数组 ["abc","efg"] 在第一种情况下,我想将它转换成一个数组,什么是好的方法? 这是我的想法 if params[:
我刚刚用 Rails new 启动了一个新的 Rails 应用程序,将默认数据库设置更改为 PostgresSQL。我用 bin/rails s 启动服务器,结果很奇怪 2016-04-21 05:0
我收到一个参数并希望它是这样的字符串: "abc,efg" 或者像这样的数组 ["abc","efg"] 在第一种情况下,我想将它转换成一个数组,什么是好的方法? 这是我的想法 if params[:
我有 Rails 4,这是我的默认版本(我仍然希望它是)。但我不想在我的电脑上添加 rails 3.2。在以下命令中:gem install rails -v 3.2.16 我有这个警告: railt
您好,我想使用 Sheevaplug 构建一个“Rails Brick”来自 Marvell(操作系统是开箱即用的 Ubuntu,但您可以在其上安装其他发行版)。它将成为家庭服务器和静音、低成本(99
我需要能够从 Rails 控制台发送我的 Rails 应用程序的 Postgres 数据库中所有未接受的邀请。 (我有一个名为 Invitations 的表,其中包含一个名为 accepted 的 b
validate :cannot_modify_if_locked, on: :update def cannot_modify_if_locked if self.locked erro
我正在学习教程(学习 Rails 播客),需要更改以下路由语法,以便它与 Rails 3.0 兼容。谁能帮忙? map.view_page ':name', :controller => 'viewe
我是一名优秀的程序员,十分优秀!