2

Thanks in advance for whoever tries to resolve my issue. I am new to rails so please help, I have

rails g scaffold City name:string
rails g scaffold Area name:string city:references
rails g scaffold User name:string brief:text
rails g migration CreateAreasUsers id:false area:references user:references

rake db:migrate

CreateAreasUsers is a table join bw area and user

City and Areas are pre-populated

Two issues

1) How to add functionality in user form so that :areas_users (join table) is also updated.

2) City and Area are separate models so how can I change select tag for city with select tag for area (however area depends on city) like:

<div id="foo">
<select>
 <% @cities.each do |city|%>
  <option value="<%=city.id%>"> <%=city.name%> </option>
 <%end%>
<select/>

 <div id="bar">
    <select>
     <% @areas.each do |area|%>
      <option value="<%=area.id%>"> <%=area.name%> </option>
     <%end%>
    <select/>
    </div>

div foo should be interchanged with div bar within the new user form Please help.

1 Answer 1

1

Okay so since you're a Rails newbie, I'll explain what you need to know.


Association

Firstly, you're dealing with ActiveRecord associations. I guess you have some idea as to how they work, as you've asked pertinent questions.

If you need to know the specifics, you've been making a has_and_belongs_to_many relationship:

enter image description here

This does not require any extra models - it gives you the ability to invoke associated data directly with the join table itself.

--

To answer your first question:

How to add functionality in user form so that :areas_users (join table) is also updated.

The answer is to pass the appropriate data through your habtm association:

#app/models/user.rb
class User < ActiveRecord::Base
    has_and_belongs_to_many :areas
end

#app/models/area.rb
class Area < ActiveRecord::Base
   has_and_belongs_to_many :users
end

This allows you to reference @user.areas and @area.users respectively, including forms:

#app/views/users/new.html.erb
<%= form_for @user do |f| %>
   <%= f.select :areas, Area.all, multiple: true %>
<% end %>

Normally you'd use accepts_nested_attributes_for for this type of functionality. This is a slightly different matter which I'd have to explain with another post.

You can then alter your @user object with the following:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def create
       @user = User.new user_params
   end

   private 

   def user_params
       params.require(:user).permit(:user, :params, :areas)
   end
end

For your second question:

City and Area are separate models so how can I change select tag for city with select tag for area (however area depends on city) like

This is a little more involved.

First of all, you need to have your associations set up correctly. I recommended the above based on what you posted; I am not a mind reader, so if it's wrong, it's because you didn't explain yourself properly.

The bottom line is that your City and Area models need to have the following associations:

#app/models/city.rb
class City < ActiveRecord::Base
    belongs_to :area
end 

#app/models/area.rb
class Area < ActiveRecord::Base
    has_many :cities
end

This means that you'll be able to call @city.area and @area.cities. As such, you'll be able to load a form as follows:

What you need to do is create a way for the selectbox to pull the associated values from your server. Whilst there is likely a gem or simpler way to do this, I'll just write it for you whilst I'm in the mood:

#config/routes.rb
resources :areas do
    get ":id/cities", to: "areas#show" # -> we'll be using the 'show' action
end 

#app/controllers/areas_controller.rb
class AreasController < ApplicationController
    def show
       @area = Area.find params[:id]
       respond_to do |format|
          format.html
          format.json { render json: @area.cities }
       end
    end
end

This gives us a hook with which we can use Ajax to pull the relevant cities when an area is selected:

#app/assets/javascripts/application.js
$("select.areas").on("change", function(){
   id = $(this).val();
   $.ajax({
      url: id + "/cities"
      success: function(data) {
         cities = JSON.Parse(data);
         $('select.cities').find('option').remove();
         $.each(cities, function(index, item) {
            $("select#cities").append( // Append an object to the inside of the select box
            $("<option></option>") // Yes you can do this.
               .text(item.description)
               .val(item.id)
            );
        });
      }
   });
});
Sign up to request clarification or add additional context in comments.

1 Comment

Million thanks for answer it was a great help.. but I am still stuck in same situation (perhaps I framed My question wrong) Associations Migrations is fine the issue is my areas_users table is not updated with new user form how to add this functionality. Plus the select tag for city and area should change within new user form so that I can use that area to update my areas_users table+create a new user... and I am failing to do so. U answer was a great help I learned 1 new thing .. and ya thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.