问题
假设我有一个名为ServiceMenu
的脚手架,它只包含一个下拉菜单,其中包含 Brakes , Pads 和消声器的3个值。
我有Service
模型,它在名为Tech
的模型上存储属于用户的所有服务。每个tech
都可以添加service_menu
(制动, Pads 和 Muffler )中的任何一个到他们的db配置文件,名为services
。
我想到的问题是,如果我更新任何一个ServiceMenu
名称从 Brakse 到 Brakes ,techs
仍将在个人资料中使用旧的service_menu
名称。由于错误或者只是想更新ServiceMenu
名称,我发现自己会做很多内务处理,更新超过1000条记录。
文件
service_menu.rb
class ServiceMenu < ActiveRecord::Base
has_many :services
end
service.rb
class Service < ActiveRecord::Base
belongs_to :tech
belongs_to :service_menu
end
service_menus_controller.rb
def update
respond_to do |format|
if @service_menu.update(service_menu_params)
format.html { redirect_to @service_menu, notice: 'Service menu was successfully updated.' }
else
@position_count = ServiceMenu.count
format.html { render :edit }
end
end
service_controller
def new
@service = current_tech.services.build
end
def create
@service = current_tech.services.build(service_params)
respond_to do |format|
if @service.save
format.html { redirect_to @service, notice: 'Service was successfully created.' }
format.json { render :show, status: :created, location: @service }
else
format.html { render :new }
format.json { render json: @service.errors, status: :unprocessable_entity }
end
end
end
模式
create_table "service_menus", force: :cascade do |t|
t.string "name", limit: 255
t.datetime "service_icon_updated_at"
t.integer "service_icon_file_size", limit: 4
t.string "service_icon_content_type", limit: 255
t.string "service_icon_file_name", limit: 255
t.integer "position", limit: 4
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "services", force: :cascade do |t|
t.string "name", limit: 255
t.integer "tech_id", limit: 4
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "techs", force: :cascade do |t|
t.string "email", limit: 255, default: "", null: false
t.string "username", limit: 255
t.datetime "avatar_updated_at"
t.integer "avatar_file_size", limit: 4
t.string "avatar_content_type", limit: 255
t.string "avatar_file_name", limit: 255
t.string "encrypted_password", limit: 255, default: "", null: false
t.string "reset_password_token", limit: 255
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", limit: 4, default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip", limit: 255
t.string "last_sign_in_ip", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "first_name", limit: 255
t.string "last_name", limit: 255
end
问题
我可以随时执行将services
数据库中的多个记录动态更新为ServiceMenu
中更新名称的任务吗?
用词来说:
ServiceMenu
上的记录从错误 Brakse 更新为 Brakes ServiceMenu
上的记录后,Rails会在services
db中找到name
列中= Brakse name
列中的所有 Brakse 值更新为制动 修改
每当我在ServiceMenu
下拉菜单上更新任何内容时,请执行此类操作。
if @service_menu.update(service_menu_params)
@service.update.where(name: "Old `ServiceMenu` value which , ie.**Brakse**", "The new `ServiceMenu` value which is now **Brakes**")
请帮忙说明如何做到这一点。 非常感谢任何帮助。
答案 0 :(得分:0)
除非我错过了一些问题的细微差别,否则您需要将服务项目从Brakse重命名为Brake - 关联将保持有效。
当然,这假定services
表有一个name
字段,但如果没有看到你的架构,很难知道。
如果这不是正确答案,请显示整个架构,而不仅仅是关联。
答案 1 :(得分:0)
在Rails中,您可以通过在实体之间创建模型关系来实现这一点。在您的情况下,具体来说,看起来像这样:
class Tech < ActiveRecord::Base
has_many :services, inverse_of: :tech
end
class Service < ActiveRecord::Base
belongs_to :tech, inverse_of: :services
belongs_to :service_menu, inverse_of :services
end
class ServiceMenu < ActiveRecord::Base
has_many :services, inverse_of: :service_menu
end
现在,如果Service
模型在数据库中有一个名称列(在这种情况下应该是这样),那么只要在数据库中更新该属性,它也将为每个用户更新,因为它们所有都与同一个数据库表有关系。
简而言之,如果您为模型添加适当的关系(如上所列),您将不必担心任何类型的问题。这就是面向对象编程的美妙。
请注意:您当前的模型结构的设置方式,Service
类,Tech
类以及{{{} ServiceMenu
类需要外键引用1}}类。迁移看起来像这样:
rails generate migration AddTechAndServiceMenuRefToServices tech:references service_menu:references
该迁移会将tech_id
和service_menu_id
列添加到您的Service
类,从而在您的不同模型之间创建正确的关系。
答案 2 :(得分:0)
这些模型名称ServiceMenu和Service在此上下文中确实令人困惑,应该分别是Service和RenderedService。话虽如此,让我们看看你需要什么才能让它工作,而根本不需要更新声明。
将以下关系添加到组合中:
class ServiceMenu < ActiveRecord::Base
has_many :services
end
class Service < ActiveRecord::Base
belongs_to :service_menu
belongs_to :tech
end
class Tech < ActiveRecord::Base
has_many :services
end
服务模型现在使用其名称来引用ServiceMenu,这是您的混淆所在。而不是名称,让服务模型通过创建类似的迁移使用service_menu_id引用ServiceMenu:
rails generate migration AddServiceMenuIdToServices service_menu_id:references
完成这些更改后,您需要调整代码以使用服务模型中的新service_menu_id列。
如果以前你做过类似的事情:
s = Service.new(name: 'Brakes', tech: Tech.find_by(name: 'Bob'))
你现在应该这样做:
s = Service.new(service_menu: ServiceMenu.find_by(name: 'Brakes'), tech: Tech.find_by(name: 'Bob'))
现在,Saving s将保存对当前名为&#39; Brakes&#39;的特定ServiceMenu项目的引用。如果您将来将此特定ServiceMenu项目的名称更改为&#34; Barkes&#34;该更改将自动反映在服务模型中,因为它不再在服务记录中存储服务菜单项的名称。
如果您之前使用的是:
s = Service.find(100)
puts s.name
要检索服务所指的服务菜单项的名称,现在您可以使用以下内容:
s = Service.find(100)
puts s.service_menu.name
您在服务模型中仍然有一个名称字段需要使用迁移删除。如果您在此系统中有现有数据,则需要使用名称字段中的数据填充所有服务模型的service_menu_id字段。