sups wrote in post #1097037:
Hi Helpers, I am new to Ruby in Rails and I have difficulty it passing the instance varaibles to the view. Earlier I was reading the values from the table directly in the view. Now I want to do that part in controller below is my code before changes
Welcome to Ruby on Rails.
view.... <%= javascript_include_tag :defaults %> <% form_tag( {:action => 'show'},{:method => :post}) %> <br><br> <b>Enter ComponentName <p>Search for a component to add or move </p> <% @complist = Components.find(:all, :select => 'DISTINCT component_name') %>
It's a really good thing that you have come to us for advice. The above code completely breaks the Model View Controller (MVC) design pattern that Rails is built upon.
A view should NOT (dare I say NEVER) send messages directly to a model object. Components.find(...) is a message being sent directly to the model "Components" from your view.
I also noticed that you've thrown in (:select -> DISTINCT) in there. Unless you are doing something really odd, for a very specific caae, I'm betting this is unnecessary. If you need it for some reason, that reason is more than likely that you're doing something wrong. This is a big red flag to me just looking at the code you've shown here.
Move this to the controller...
def show @components = Components.all end
In your view use the proper model based form helper. You can read all about that in the Rails Guides here...
In fact I would highly recommend that you stop everything now and read through:
This is a really great place to start learning how to do Ruby on Rails the "right" way.
<%= select_tag "component_name",options_for_select([""]+@complist.map{|u| [u.component_name]}),:include_blank => true,:onchange => remote_function(:url => {:action => :setselectedcomp },:with => "'component_name='+value" ) %> <%= observe_field(:component_name,:controller => :comp_groups_controller, :url => {:action => 'select_groups'}, :update => :group_names, :with => "'component_name='+value" ) %> <br>
My recommendation here is to back off using more advanced features like observe_field until you actually understand the basics of Rails MVC design patterns. Keep the client side JavaScript stuff out of the picture until you understand what standard Rails views, controllers and models look like in a purely server side web application.
controller........
def setselectedcomp() $selected_comp = params["component_name"] puts "selected_comp: #{$selected_comp}" $selected_comp_id = Components.find(:all, :select => ['component_id'], :condition => ["component_name = '#{$selected_comp}'"]) puts "selectd_comp_id is #{$selected_comp_id}" end def select_groups passing_comp = params["component_name"] puts "passing comp = #{passing_comp}" @belongstogroup = CompGroups.find(:all, :select => ['group_name'], :conditions => ["component_name = '#{passing_comp}'"]) belongstogroup.each do |num| puts num.inspect end #return @belongstogroup render :partial => "select_groups" end This is working perfectly fine
It might seem to be "working perfectly fine," but these methods do not follow standard Rails design patterns. Any experienced Rails developer would tell you the same thing. One day you may need to collaborate with other Rails developers and this would not get you off to a good start in that relationship.
Again the Rails Guides show a number of typical patterns. Here's one for listing Posts:
Notice the standard naming schemes used in the controller:
def index @posts = Post.all ... ... end
Then notice how the view uses the data that was loaded by the controller from the Post model.
1. The request is directed to the controller through the routing system. 2. The controller loads the data by sending a message to the model (or models). 3. The controller renders the view, providing the loaded data through some Rails black magic (i.e. it makes the @posts instance variable available to the view). 4. The view loops through the @posts by sending the "each" method to the array object provided by the controller.
We now live in the happy land of MVC. The controller coordinates all communication between the model layer and the view layer. The view and model have no direct knowledge of each other.
<% @posts.each do |post| %> <tr> <td><%= post.name %></td> <td><%= post.title %></td> <td><%= post.content %></td> <td><%= link_to 'Show', post %></td> <td><%= link_to 'Edit', edit_post_path(post) %></td> <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td> </tr> <% end %>
Even this is often considered to be too much logic for the view, so next it's time to clean things up by factoring out the rendering of the collection to a partial.
Read this for further explanation:
What I wanted to accomplish is 1. in the select_tag I have added the "include_blank=true" to allow user to add a value. it sisn't work for me. May i know what I did wrong 2. I am not getting the component_id value in the controller. Not sure what I did wrong $selected_comp_id = Components.find(:all, :select => ['component_id'], :condition => ["component_name = '#{$selected_comp}'"]) puts "selectd_comp_id is #{$selected_comp_id}"
I'll defer any attempt to answer these questions until after you get a decent grasp of the fundamentals. I'd suggest you do the same.