所以我知道如何覆盖ActiveRecord对象的属性的默认getter
def custom_getter
return self[:custom_getter] || some_default_value
end
Run Code Online (Sandbox Code Playgroud)
我试图实现相同的东西,但属于一个属于协会.例如.
class Foo < AR
belongs_to :bar
def bar
return self[:bar] || Bar.last
end
end
class Bar < AR
has_one :foo
end
Run Code Online (Sandbox Code Playgroud)
当我说:
f = Foo.last
Run Code Online (Sandbox Code Playgroud)
我想让方法f.bar
返回最后一个Bar,而不是nil,如果该关联还不存在.
但这不起作用.原因是self [:bar]总是未定义的.它实际上是自我[:bar_id].
我可以做一些天真的事情:
def bar
if self[:bar_id]
return Bar.find(self[:bar_id])
else
return Bar.last
end
end
Run Code Online (Sandbox Code Playgroud)
但是,即使已经获取了Bar,这也总是会进行db调用,这当然不是理想的.
有没有人能够了解我如何建立关系,以便belongs_to属性只加载一次,如果没有设置则具有默认值.
我已经查看了Ruby on Rails指南,我似乎无法弄清楚如果有父级记录,如果有人删除父记录.例如.如果我的数据库有CUSTOMERS并且每个客户可以有多个ORDERS,我想阻止有人在数据库中有任何订单时删除客户.如果客户没有订单,他们应该只能删除客户.
在定义模型之间的关联以强制执行此行为时,有没有办法?
我试图测试以下场景:
- >我有一个名为Team的模型,它在用户创建时才有意义.因此,每个Team实例都必须与用户相关.
为了测试,我做了以下事情:
describe Team do
...
it "should be associated with a user" do
no_user_team = Team.new(:user => nil)
no_user_team.should_not be_valid
end
...
end
Run Code Online (Sandbox Code Playgroud)
这迫使我将团队模型更改为:
class Team < ActiveRecord::Base
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :user
validates_presence_of :name
validates_presence_of :user
belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)
这对你来说是否正确?我只是担心将:user属性设为可访问(质量分配).
我想做什么:
我有一个博客,想在主帖后面显示相关帖子.
class Post < ActiveRecord::Base
has_many :related_posts
has_many :posts, :through => :related_posts
end
Run Code Online (Sandbox Code Playgroud)
然后在连接模型/表中
class RelatedPost < ActiveRecord::Base
belongs_to :post
end
Run Code Online (Sandbox Code Playgroud)
当然还有一个叫related_posts
两post_id
列的表.
显然这有几个缺点,我只是不确定如何在Rails中使这个关联工作.
如何在不删除项目本身的情况下删除HABTM关联项目?
例如,假设我有3名学生一起参加科学课程.如何从StudentsClasses表中删除Science对象而不删除实际的Science参考?我猜这 Student.Classes.first.delete
不是一个好主意.
我使用拖放式JavaScript进行添加和删除,而不是复选框.有什么想法吗?
在我的应用程序中,a user
有很多score_cards
,score_card
属于auser
问题是,每当我创建一个新的score_card
,即被ScoreCardsController.create
调用时,如何将这个新创建添加score_card
到current_user
(我正在使用设计,因此current_user
是一个有效的User
对象).
我有一个模型,PointOfContact
其中has_many
Systems
.从Systems
侧面我想要识别PointOfContact
为technical_manager
或project_manager
(或两者).虽然仍然只PointOfContact
在DB中保留1次.
我的尝试如下:
class System < ActiveRecord::Base
belongs_to :project_manager, :class_name => 'PointOfContact'
belongs_to :technical_manager, :class_name => 'PointOfContact'
end
class PointOfContact < ActiveRecord::Base
has_many :systems
end
Run Code Online (Sandbox Code Playgroud)
当我运行我的规范(示例如下)时,我可以正确地创建System
联系点关联.但是,PointOfContact
它并不知道它与System的关联.这是为什么?
@sys = System.create
@tm = PointOfContact.create
@pm = PointOfContact.create
@sys.project_manager = @pm
@sys.technical_manager = @tm
@pm.systems.should have(1).items #> expected 1 items, got 0
Run Code Online (Sandbox Code Playgroud) 我的Rails应用程序中的用户和角色之间存在标准的多对多关系:
class User < ActiveRecord::Base
has_many :user_roles
has_many :roles, :through => :user_roles
end
Run Code Online (Sandbox Code Playgroud)
我想确保只为用户分配一次角色.任何插入重复项的尝试都应该忽略该请求,而不是抛出错误或导致验证失败.我真正想要表示的是"集合",其中插入已存在于集合中的元素无效.{1,2,3} U {1} = {1,2,3},而非{1,1,2,3}.
我意识到我可以这样做:
user.roles << role unless user.roles.include?(role)
Run Code Online (Sandbox Code Playgroud)
或者通过创建一个包装器方法(例如add_to_roles(role)
),但我希望通过关联使其自动化的一些惯用方法,以便我可以写:
user.roles << role # automatically checks roles.include?
Run Code Online (Sandbox Code Playgroud)
它只是为我做的工作.这样,我不必记得检查重复或使用自定义方法.我缺少框架中的某些东西吗?我首先想到:has_many的uniq选项可以做到,但它基本上只是"选择不同的".
有没有办法以声明方式做到这一点?如果没有,可能使用关联扩展名?
以下是默认行为失败的示例:
>> u = User.create User Create (0.6ms) INSERT INTO "users" ("name") VALUES(NULL) => #<User id: 3, name: nil> >> u.roles << Role.first Role Load (0.5ms) SELECT * FROM "roles" LIMIT 1 UserRole Create (0.5ms) INSERT INTO "user_roles" ("role_id", "user_id") VALUES(1, 3) Role Load …
1)我知道autosave: true
根据http://railsapi.com/doc/rails-v2.3.8/classes/ActiveRecord/AutosaveAssociation.html保存关联
2)我知道它将保存像这样构造的关联
book = Book.new(name: 'foo')
book.authors.build(name: 'bar') #has_many
book.save
Run Code Online (Sandbox Code Playgroud)
或者喜欢
book = Book.new(name: 'foo')
book.build_author(name: 'bar') #has_one
book.save
Run Code Online (Sandbox Code Playgroud)
3)我认为在分配或添加关联时也会保存关联
book = Book.new(name: 'foo')
book.author = Author.new(name: 'bar')
book.save
Run Code Online (Sandbox Code Playgroud)
要么
book = Book.new(name: 'foo')
book.authors << Author.new(name: 'bar')
book.save
Run Code Online (Sandbox Code Playgroud)
但是,我有一个复杂的错误,涉及的东西不能自动保存,当我期望它.因此,我希望通过检查进行调试,book
以验证我认为将要保存的内容实际上将被保存.
TL; DR; 保存关联时检查什么内部状态?我假设一个模型有一个内部实例变量,就像associations_to_save
在创建它们时添加了关联.然后,当保存模型时,它会遍历这些关联并保存它们.
在Rails中,我一直(小时)遇到麻烦.我发现了很多类似的问题,但我不能申请我的案子:
城市班级:
class City < ApplicationRecord
has_many :users
end
Run Code Online (Sandbox Code Playgroud)
用户班级:
class User < ApplicationRecord
belongs_to :city
validates :name, presence: true, length: { maximum: 80 }
validates :city_id, presence: true
end
Run Code Online (Sandbox Code Playgroud)
用户控制器:
def create
Rails.logger.debug user_params.inspect
@user = User.new(user_params)
if @user.save!
flash[:success] = "Works!"
redirect_to '/index'
else
render 'new'
end
end
def user_params
params.require(:user).permit(:name, :citys_id)
end
Run Code Online (Sandbox Code Playgroud)
用户查看:
<%= form_for(:user, url: '/user/new') do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :citys_id, "City" %> …
Run Code Online (Sandbox Code Playgroud) validation ruby-on-rails associations belongs-to model-associations
associations ×10
activerecord ×3
belongs-to ×1
has-many ×1
idioms ×1
model ×1
rspec ×1
validation ×1