Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails—如何更新记录,然后根据被修改记录的值动态更新另一个模型上的值?_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails Rails—如何更新记录,然后根据被修改记录的值动态更新另一个模型上的值?

Ruby on rails Rails—如何更新记录,然后根据被修改记录的值动态更新另一个模型上的值?,ruby-on-rails,ruby,Ruby On Rails,Ruby,问题 假设我有一个名为ServiceMenu的脚手架,它只包含一个下拉菜单,其中有三个值:刹车、刹车片和消音器。 我有一个Service模型,它将属于用户的所有服务存储在一个名为Tech的模型上。每个技术都能够将维修_菜单中的任何一个(制动器、刹车片和消声器)添加到其数据库配置文件中,该配置文件称为维修 我所看到的问题是,如果我更新了维修菜单中的任何一个名称,比如从Brakse到Brakes,技术人员的配置文件中仍然会有旧的维修菜单名称。我会发现,由于输入错误或只是想更新服务菜单名称,我会做很多

问题

假设我有一个名为
ServiceMenu
的脚手架,它只包含一个下拉菜单,其中有三个值:刹车、刹车片和消音器。 我有一个
Service
模型,它将属于用户的所有服务存储在一个名为
Tech
的模型上。每个
技术
都能够将
维修_菜单
中的任何一个(制动器、刹车片和消声器)添加到其数据库配置文件中,该配置文件称为
维修

我所看到的问题是,如果我更新了
维修菜单
中的任何一个名称,比如从Brakse到Brakes,
技术人员
的配置文件中仍然会有旧的
维修菜单
名称。我会发现,由于输入错误或只是想更新
服务菜单
名称,我会做很多家务工作来更新1000多条记录


文件

服务菜单.rb

class ServiceMenu < ActiveRecord::Base
  has_many :services
end
class Service < ActiveRecord::Base
  belongs_to :tech
  belongs_to :service_menu
end
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
服务控制器

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

问题

我如何执行将
服务
数据库中的多条记录动态更新为
服务菜单
中更新名称的任务? 顺序如下:

  • 更新
    维修菜单
    上从输入错误Brakse到Brakes的记录
  • 更新
    服务菜单
    上的记录后,Rails将在
    服务
    数据库中找到
    名称
    列中所有=Brakse的值
  • name
    列中的所有Brakse值更新为Brakes

编辑

每当我更新
服务菜单
下拉菜单上的任何内容时,请执行类似操作

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**")
请就如何完成这一点提供帮助。
非常感谢您的帮助。

除非我遗漏了问题的一些细微差别,否则您只需将服务项目从Brakse重命名为Brake即可——关联将保持有效

当然,这假设
services
表有一个
name
字段,但是如果不查看您的模式,就很难知道


如果这不是正确答案,请显示整个模式,而不仅仅是关联

在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
rails generate migration AddTechAndServiceMenuRefToServices tech:references service_menu:references

该迁移将把
tech\u id
service\u menu\u id
列添加到
service
类中,从而在不同的模型之间建立适当的关系

这些模型名称ServiceMenu和Service在此上下文中非常容易混淆,应该分别为Service和RenderService。话虽如此,让我们看看在根本不需要update语句的情况下,您需要什么来让它工作

将以下关系添加到组合中:

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
一旦进行了这些更改,您就需要调整代码以使用服务模型中的新服务菜单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'))
s = Service.find(100)
puts s.name
s = Service.find(100)
puts s.service_menu.name
您现在应该执行以下操作:

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'))
s = Service.find(100)
puts s.name
s = Service.find(100)
puts s.service_menu.name
保存s将保存对当前称为“制动器”的特定维修菜单项的引用。如果将来将此特定服务菜单项的名称更改为“Barkes”,则此更改将自动反映在服务模型中,因为它不再将服务菜单项的名称存储在服务记录中

如果您以前使用过类似以下内容:

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'))
s = Service.find(100)
puts s.name
s = Service.find(100)
puts s.service_menu.name
要检索服务所引用的服务菜单项的名称,现在您可以使用如下内容:

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'))
s = Service.find(100)
puts s.name
s = Service.find(100)
puts s.service_menu.name

在服务模型中仍然有一个名称字段,需要使用迁移删除该字段。如果此系统中存在数据,则需要使用名称字段中的数据填充所有服务模型的服务菜单id字段。

我已添加了与此帖子相关的架构内容。迁移更像是一个手动过程。我正在寻找一个更具活力的解决方案。我还提供了更多细节。嗨,贾维德,谢谢你的回复。
维修菜单
是一个包含单个车辆项目菜单的页面,如制动器、减震器、消音器等。。。。
服务菜单
是一个受限页面,仅管理员可以访问。我希望
Techs
或其他任何人不要在此菜单中添加或删除菜单项。您提到的,除了
服务菜单\u id
迁移之外,我已经准备好了。然而,我未能达到预期的结果。正如下面柯林的帖子中所提到的,我在
service\u菜单
更新操作中使用了这个选项:
service.where(name:@temp\u var).update\u all(name:@service\u menu.name)
编辑
操作中使用了这个选项。然而,where子句不识别VAR,而是实际的“stings”嗨,科林,我非常感谢你的回答。除了迁移,我已经添加了您提到的所有内容。因为我已经有了上一次迁移中的
tech
外键,所以我改为执行以下操作:在创建
add\u reference:services、:service\u menu、index:true
add\u外键:services、:service\u menu之后,在::name
之后添加服务。我已重新启动服务器并多次执行您的指示,但不幸的是无法达到预期的结果。我想我可能遇到的是,我正在使用
@service=**current_tech**.services.build
。由于我正在创建一个新服务作为
当前的\u tech
(设计助手),因此只有
技术id
将应用于
服务
数据库,而不是
服务id
。看来我可以再次感谢你的帮助。我得到的最后结果