0

I have a admin controller to create "Locations", inside of which is a form. In the form you can create a new "Location" and give it a name, description, and "exits".

<%= form_for @location do |f| %>
    <p>
        <%= f.label :name %><br>
        <%= f.text_field :name %>
    </p>

    <p>
        <%= f.label :description %><br>
        <%= f.text_area :description %>
    </p>

    <p>
        Exits:
        <br/>
        <% @locations.each do |e| %>
            <%= f.label :locations %>
            <%= f.check_box :locations %>
        <% end %>
    </p>

    <p>
        <%= f.submit %>
    </p>
<% end %>

@locations is all of the available locations to set up as an "exit". I'm trying to create an array of locations inside of the new location using checkboxes to check whether or not they should be set as "exits", but not really sure how to proceed since i'm just teaching myself and it's day one.

I'm also wondering how to set up the "exits" in the Location model. Right now i have:

class Location < ActiveRecord::Base
    has_many :locations
    validates :name, presence: true, length: { minimum: 1 }
    validates :description, presence: true
end

created with:

class CreateLocations < ActiveRecord::Migration
  def change
    create_table :locations do |t|

      t.string :name
      t.text :description
      t.references :location, index: true, foreign_key: true

      t.timestamps null: false
    end
  end
end

But i would like to have them referenced as "exits" not "locations" (ie Location.exits instead of Location.locations).

UPDATE

I've updated the form to use the collection_check_boxes helper

<%= f.collection_check_boxes(:exit_ids, @locations, :id, :name) do |cb| %>
    <%= cb.label %> <%= cb.check_box %> <br/>
<% end %>

So I have this in the create action now

    def create
        @location = Location.new(location_params)

        if @location.save
            params[:location][:exit_ids].each do |e|
                if e.to_i > 0
                    tempLocation = Location.find(e.to_i)
                    @location.allowExitTo(tempLocation)
                end
            end
            redirect_to @location
        else
            render 'new'
        end
    end

Which goes allows exits through:

def allowExitTo(other_location)
    exit_locations.create(to_id: other_location.id)
end

creating an exit relationship with:

class Exit < ActiveRecord::Base
    belongs_to :from, class_name: 'Location'
    belongs_to :to, class_name: 'Location'

    validates :from_id, presence: true
    validates :to_id, presence: true
end

Hope I'm on the right track. It seems to work so I guess so.

Evan Ward
  • 1,371
  • 2
  • 11
  • 23
  • Have a look at `collection_chack_boxes` method: http://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_check_boxes. You can use it with a form helper as well like `f.collection_check_boxes(:locations, @locations, :id, :name)` – BroiSatse Jul 22 '15 at 23:27
  • Might be braindead from working but ruby api docs seem to read a bit like gibberish to me. Also, how can i set a value in an array to true/false based on them being checked? – Evan Ward Jul 22 '15 at 23:36

1 Answers1

0

Edit: Sorry, I must have had a brain-fart or something. You're not doing a simple has-many and belongs-to relationship, you want a has-many-and-belongs-to-many relationship. That's more complicated than I know how to explain. But this answer explained it very well: Many-to-many relationship with the same model in rails?

You can get Location#exits instead of Location#locations by changing the name of the has_many relation like this:

class Location < ActiveRecord::Base
  # has_many :locations   Instead of this...
  has_many :exits, :class_name => 'Location' # ...Do this
  validates :name, presence: true, length: { minimum: 1 }
  validates :description, presence: true
end

This is called a self-join. You're associating a model with itself.

Keep in mind that this will make Location#locations unavailable.

Then in your form you would do something like:

<% @locations.each do |e| %>
  <%= f.label :exit %>
  <%= f.check_box :exit %>
<% end %>

The Ruby on Rails site has a nice guide about associations, includeing self-joins like what you're asking about: http://guides.rubyonrails.org/association_basics.html#self-joins

If you like RailsCasts: http://railscasts.com/episodes/163-self-referential-association

Community
  • 1
  • 1
spejamchr
  • 178
  • 2
  • 8
  • Thanks for this. Is there a way i can make the `exits` reference contain `locations` that are checked, and not contain those that are unchecked? – Evan Ward Jul 22 '15 at 23:56