Rails:自动建立一对多关系的脚手架

发布于 2024-07-12 06:16:45 字数 487 浏览 11 评论 0原文

不确定我读的是否正确,但 Scaffold 似乎不会完全建立一对多关系。 例如,如果我使用脚手架创建消息,然后我想要对这些消息进行注释(一条消息 -> ;很多评论),我必须经历并改变一切。 例如,我必须在 commentnew 视图中将其更改为此

<% form_for(@comment) do |f| %>

<% form_for([@message, @comment]) do |f| %>

然后更改操作以设置 @message var ...除其他外。

目前这无法使用 Scaffold 自动完成,对吧?

Not sure if I'm reading this right, but it seems like Scaffold will not do a one-to-many relationship in its entirety. For instance, if I create messages with scaffold and then I want comments on those messages (one message -> many comments), I have to go through and change everything. For instance, I have to change this in the comment's new view

<% form_for(@comment) do |f| %>

to this

<% form_for([@message, @comment]) do |f| %>

and then change the Action to set up the @message var... amongst other things.

This cannot currently be done automatically with Scaffold, right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

风启觞 2024-07-19 06:16:45

是的。 脚手架适用于模型和相关控制器。 它不关心或处理人际关系。

Scaffold 的主要目标是使用控制器和相关视图在模型上进行 CRUD。 就这样。 任何其他要求(例如关系)都必须手动编码。

Yes. Scaffold works for a model and related controller. It does not take care of or work with relationships.

Scaffold's primary objective is to get CRUD going on a model using a controller and related views. That's all. Any other requirement like relationships has to be coded manually.

尴尬癌患者 2024-07-19 06:16:45

这是事实,但是,这还不是故事的结局。 Scaffold 至少有两种替代方案,它们都工作得很好,并且自动获取类之间的关系(基于 ActiveRecord 关系指示器,如 has_many)。 其中一种替代方案是 Streamlined,另一种是 ActiveScaffold

它们主要有助于输入系统所需的数据,而不是用户输入的数据。 例如,我将它们用于表上的管理任务,当其中一个脚手架替代方案可以很好地完成很少使用的功能时,为 CRUD 构建完整的 UI 是没有意义的。 不过,您不会想使用它们来评论消息。

This is true, but, it's not the end of the story. There are at least two alternatives to Scaffold that both work quite well and automatically pick up on relationships between classes (based on your ActiveRecord relationship indicators like has_many). One of these alternatives is Streamlined and the other is ActiveScaffold.

They're mainly helpful for entering in data that your system requires that is not user entered data. For example, I use them for administrative tasks on tables where there's no point in building a complete UI for CRUD when one of the scaffold alternatives will do the job just fine for a seldom used feature. You wouldn't want to use them for comments on messages though.

枯叶蝶 2024-07-19 06:16:45

请注意,有像 Hobo for Rails 这样的项目,允许您将字段和关联保留在模型本身内。 你无法构建关联,但它非常接近。

你最终会因为在你背后构建更多的应用程序而付出代价。 您通常不是自行推出,而是从大量预先构建的行为中减去您需要的内容。

Note that there are projects like Hobo for Rails which allow you to keep your fields and associations within the model itself. You can't scaffold associations, but it's pretty close.

You end up paying for this sugar by having a lot more of the application built behind your back. Instead of rolling your own, you're usually subtracting out what you need from a large bank of prebuilt behaviors.

治碍 2024-07-19 06:16:45

您不需要繁重的 Rails 管理框架来使一对多关系正常工作。

您可以使用脚手架来完成大部分任务。

在控制器和 _form 视图中多做一点工作就可以完成剩下的工作。

方法如下...

Story: Select a beer for a developer

In order to select a beer for a developer
As an admin
I want a mainly scaffolded interface to select that beer

Scenario 1: Select beer for new developer
Given I have clicked the <new> button  and entered the developer's name
When I click the beer dropdown
Then I should be presented with a list of beers to choose from
And that beer will be saved when I click <ok>

Scenario 2: Select a different beer for existing developer
Given I have clicked the <edit> button on the index page for a particular developer
When I click the beer dropdown
Then I should be presented with a list of beers to choose from
And that beer will be saved when I click <ok>

假设我们有一个 beers 表:

  create_table "beers", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

以及一个 developers 表,该表具有引用 beers 表的外键 (beer_id):

  create_table "developers", force: true do |t|
    t.string   "name"
    t.integer  "beer_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

我们可以使用脚手架来创建这两个表表:

$rails g 脚手架啤酒名称

$rails g 脚手架开发者姓名 beer_id:integer

命令为每个模型创建控制器和视图。

我们需要稍微修改我们的控制器和视图,以获得为每个开发人员选择啤酒的下拉菜单:

app/views/developers/_form.html.erb

将生成的 text_field 和 label 替换为beer_id 包含以下内容:

  <div class="field">
    <%= f.label :beer_id %><br />
    <%= collection_select(:developer, :beer_id, @beers, :id, :name, {:prompt => false}) %> 
  </div>

app/controllers/developer_controller.rb

编辑控制器的新方法和编辑方法:

  # GET /developers/new
  def new
    @developer = Developer.new
    @beers = Beer.all
    respond_to do |format|
      format.html # new.html.erb
    end
  end


  # GET /developers/1/edit
  def edit
    @beers = Beer.all
    respond_to do |format|
      format.html # new.html.erb
    end    
  end

屏幕截图

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

注释

Rails 脚手架很棒。 查看它为您创建的所有文件:

$ be rails g scaffold beer name
      invoke  active_record
      create    db/migrate/20140912144218_create_beers.rb
      create    app/models/beer.rb
      invoke    rspec
      create      spec/models/beer_spec.rb
      invoke      factory_girl
      create        spec/factories/beers.rb
      invoke  resource_route
       route    resources :beers
      invoke  scaffold_controller
      create    app/controllers/beers_controller.rb
      invoke    erb
      create      app/views/beers
      create      app/views/beers/index.html.erb
      create      app/views/beers/edit.html.erb
      create      app/views/beers/show.html.erb
      create      app/views/beers/new.html.erb
      create      app/views/beers/_form.html.erb
      invoke    rspec
      create      spec/controllers/beers_controller_spec.rb
      create      spec/views/beers/edit.html.erb_spec.rb
      create      spec/views/beers/index.html.erb_spec.rb
      create      spec/views/beers/new.html.erb_spec.rb
      create      spec/views/beers/show.html.erb_spec.rb
      create      spec/routing/beers_routing_spec.rb
      invoke      rspec
      create        spec/requests/beers_spec.rb
      invoke    helper
      create      app/helpers/beers_helper.rb
      invoke      rspec
      create        spec/helpers/beers_helper_spec.rb
      invoke    jbuilder
      create      app/views/beers/index.json.jbuilder
      create      app/views/beers/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/beers.js.coffee
      invoke    scss
      create      app/assets/stylesheets/beers.css.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.css.scss

您所要做的就是知道当您需要的不仅仅是基本的 CRUD 操作时要修改哪些文件。

希望有帮助。
〜莱克斯

You don't need a heavy rails admin framework to get one-to-many relationships working.

You can use scaffolding to get most of the way there.

A little more work in the controller and _form view will get you the rest of the way there.

Here's how...

Story: Select a beer for a developer

In order to select a beer for a developer
As an admin
I want a mainly scaffolded interface to select that beer

Scenario 1: Select beer for new developer
Given I have clicked the <new> button  and entered the developer's name
When I click the beer dropdown
Then I should be presented with a list of beers to choose from
And that beer will be saved when I click <ok>

Scenario 2: Select a different beer for existing developer
Given I have clicked the <edit> button on the index page for a particular developer
When I click the beer dropdown
Then I should be presented with a list of beers to choose from
And that beer will be saved when I click <ok>

Assuming we have a beers table:

  create_table "beers", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

And a developers table that has a foreign key (beer_id) referencing the beers table:

  create_table "developers", force: true do |t|
    t.string   "name"
    t.integer  "beer_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

We can use scaffolding to create both tables:

$ rails g scaffold beer name

$ rails g scaffold developer name beer_id:integer

The scaffold command creates the controllers and views for each model.

We will need to modify our controllers and views a little bit to get the dropdown menu to select a beer for each developer:

app/views/developers/_form.html.erb

Replace the generated text_field and label for beer_id with the following:

  <div class="field">
    <%= f.label :beer_id %><br />
    <%= collection_select(:developer, :beer_id, @beers, :id, :name, {:prompt => false}) %> 
  </div>

app/controllers/developer_controller.rb

Edit the controller's new and edit methods:

  # GET /developers/new
  def new
    @developer = Developer.new
    @beers = Beer.all
    respond_to do |format|
      format.html # new.html.erb
    end
  end


  # GET /developers/1/edit
  def edit
    @beers = Beer.all
    respond_to do |format|
      format.html # new.html.erb
    end    
  end

Screen Shots

enter image description here

enter image description here

enter image description here

Notes

Rails scaffolding is great. Look at all the files that it creates for you:

$ be rails g scaffold beer name
      invoke  active_record
      create    db/migrate/20140912144218_create_beers.rb
      create    app/models/beer.rb
      invoke    rspec
      create      spec/models/beer_spec.rb
      invoke      factory_girl
      create        spec/factories/beers.rb
      invoke  resource_route
       route    resources :beers
      invoke  scaffold_controller
      create    app/controllers/beers_controller.rb
      invoke    erb
      create      app/views/beers
      create      app/views/beers/index.html.erb
      create      app/views/beers/edit.html.erb
      create      app/views/beers/show.html.erb
      create      app/views/beers/new.html.erb
      create      app/views/beers/_form.html.erb
      invoke    rspec
      create      spec/controllers/beers_controller_spec.rb
      create      spec/views/beers/edit.html.erb_spec.rb
      create      spec/views/beers/index.html.erb_spec.rb
      create      spec/views/beers/new.html.erb_spec.rb
      create      spec/views/beers/show.html.erb_spec.rb
      create      spec/routing/beers_routing_spec.rb
      invoke      rspec
      create        spec/requests/beers_spec.rb
      invoke    helper
      create      app/helpers/beers_helper.rb
      invoke      rspec
      create        spec/helpers/beers_helper_spec.rb
      invoke    jbuilder
      create      app/views/beers/index.json.jbuilder
      create      app/views/beers/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/beers.js.coffee
      invoke    scss
      create      app/assets/stylesheets/beers.css.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.css.scss

All you have to do is know which files to modify when you want more than basic CRUD operations.

Hope that helps.
~ Lex

关于从前 2024-07-19 06:16:45

脚手架就是脚手架。 当您想要表上除 CRUD 之外的任何内容(这就是脚手架的作用)时,您需要更改生成的脚手架代码,或者推出您自己的脚手架代码。

Scaffolds are scaffolds. When you want anything other than a CRUD on a table (which is what a scaffold is/does), you need to alter the generated scaffolding code, or roll your own.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文