Rails: Scaffold to automatically do one-to-many relationship

前端 未结 5 1556
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-09 10:55

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

5条回答
  •  独厮守ぢ
    2020-12-09 11:35

    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  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 
    
    Scenario 2: Select a different beer for existing developer
    Given I have clicked the  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 
    

    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:

      
    <%= f.label :beer_id %>
    <%= collection_select(:developer, :beer_id, @beers, :id, :name, {:prompt => false}) %>

    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

提交回复
热议问题