say I have a text field like the following in a view called 'search':
<%= text_field_tag(:lookup) %>
how do I submit this ':lookup' value and pass it into the controller called 'search' and assign it to a variable?
It's a basic problem, but being a noob, it's difficult ;)
That will be accessible in the controller as
params[:lookup]
Your controller could look something like this:
class SearchesController < ActionController::Base
def search
lookup = params[:lookup]
#models = Model.find_by_lookup(lookup)
end
end
And your view should look like this:
<%= form_tag searches_path do %>
<label for="lookup">Lookup</label>
<%= text_field_tag :lookup %>
<%= submit_tag "Submit" %>
<% end %>
Related
I have created a simple form to create an instance of a modle and for some reason it is not calling the create method in the controller. Here is the form code:
<% #house.mates.each do |mate| %>
<p><%= mate.name %></p>
<% end %>
<h2>Add a new mate:</h2>
<%= form_for #mate do |f| %>
<p><%= f.label "Name" %>
<%= f.text_field :name %>
<%= f.hidden_field :house_id %>
</p>
<%= f.submit "Submit", :action => :create %>
<% end %>
Here is the controller code:
class MatesController < ApplicationController
def new
#mate = Mate.new
end
def create
#mate = Mate.new(params[:mate])
#mate.save
redirect_to house_path(current_house)
end
end
There is a many to one relationship between the Mate model and the House model... I am fairly new to rails but I have made other apps with similar forms, and I have never had this problem before. I can create and save Mate objects in the console, and I am not getting any errors, so it seem that somehow the controller method is not being called. Any help is much appreciated!
In fact, if other things have no problem, your #mate object should be created. You just can't see it in house page because you have not associated #mate with house in your code.
In your form you referred :house_id, but this attribute is nil when you rendering the form.
The reason is you have not assigned it in controller.
In controller you need to initialize #mate from house object to have house_id inside it
def new
#house = something
#mate = #house.mates.new # Instead of Mate.new
end
I have a partial that needs to have some controller logic run before it can render without issue. Is there some way to associate the partial with some controller logic that is run whenever it is rendered?
For example, this is what my current code looks like:
MyDataController:
class MyDataController < ApplicationController
def view
#obj = MyData.find(params[:id])
run_logic_for_partial
end
def some_method_i_dont_know_about
#obj = MyData.find(params[:id])
# Doesn't call run_logic_for_partial
end
def run_logic_for_partial
#important_hash = {}
for item in #obj.internal_array
#important_hash[item] = "Important value"
end
end
end
view.html.erb:
Name: <%= #obj.name %>
Date: <%= #obj.date %>
<%= render :partial => "my_partial" %>
some_method_i_dont_know_about.html.erb:
Name: <%= #obj.name %>
User: <%= #obj.user %>
<%# This will fail because #important_hash isn't initialized %>
<%= render :partial => "my_partial" %>
_my_partial.html.erb:
<% for item in #obj.internal_array %>
<%= item.to_s %>: <%= #important_hash[item] %>
<% end %>
How can I make sure that run_logic_for_partial is called whenever _my_partial.html.erb is rendered, even if the method isn't explicitly called from the controller? If I can't, are there any common patterns used in Rails to deal with these kinds of situations?
You should be using a views helper for this sort of logic. If you generated your resource using rails generate, a helper file for your resource should already be in your app/helpers directory. Otherwise, you can create it yourself:
# app/helpers/my_data.rb
module MyDataHelper
def run_logic_for_partial(obj)
important_hash = {}
for item in obj.internal_array
important_hash[item] = "Important value" // you'll need to modify this keying to suit your purposes
end
important_hash
end
end
Then, in your partial, pass the object you want to operate on to your helper:
# _my_partial.html.erb
<% important_hash = run_logic_for_partial(#obj) %>
<% for item in important_hash %>
<%= item.to_s %>: <%= important_hash[item] %>
<% end %>
Or:
# app/helpers/my_data.rb
module MyDataHelper
def run_logic_for_partial(item)
# Do your logic
"Important value"
end
end
# _my_partial.html.erb
<% for item in #obj.internal_array %>
<%= item.to_s %>: <%= run_logic_for_partial(item) %>
<% end %>
EDIT:
As commented Ian Kennedy points out, this logic can also reasonably be abstracted into a convenience method in your model:
# app/models/obj.rb
def important_hash
hash = {}
for item in internal_array
important_hash[item] = "Important value"
end
hash
end
Then, you'd access the important_hash attribute in the following manner in your partial:
# _my_partial.html.erb
<% for item in #obj.important_hash %>
<%= item.to_s %>: <%= item %>
<% end %>
What you're trying to do runs against the grain of how Rails controllers/views are designed to be used. It would be better to structure things a bit differently. Why not put run_logic_for_partial into a helper, and make it take an argument (rather than implicitly working on #obj)?
To see an example of a view "helper", look here: http://guides.rubyonrails.org/getting_started.html#view-helpers
In my form I want to iterate over a specific collection and collect the same information about each. For simplicity's sake something like:
<%= form_tag :update_dog do %>
<% #dogs.each do |dog| %>
<%= text_field_tag :name, :class=>dog.id %>
<% end %>
<%= submit_tag "Add", :class => 'btn btn-success'%>
<%= end %>
Where I would want to collect each dog's name to manipulate in the controller (in which I'd like to be able to iterate over each submitted dog name and access its id). The potential number of dogs in my collection is variable. What is the best way to do this? The code above is what I have so far but I have no idea if it's right and if so, how to use it in the controller.
Thanks so much!
I'd start with a filter. Create a before_filter that creates your dogs
class KennelController < ApplicationController
before_filter :get_dogs , :only=>[:new,:edit]
def get_dogs
#dogs = Dog.all.map{|d| [d.name, d.id]}
end
....
end
Then in either your new or edit views, you could do this:
<%= select_tag :dog, options_for_select(#dogs) %>
I created a form that you can type text with a "post" button and i want that when you type something and press the post button it will show what you wrote.
My question is: What is the code to connect between the view and the controller?
This is the view i already created:(i also generated a home controller with a showmsg action)
<h1 align="center">MicroBlog</h1>
<br><br>
<div align="center">
<%= form_tag( {:controller => 'home', :action => 'showmsg'}, :method => "post") do %>
<%= text_field_tag(:p,#postword) %>
<%= submit_tag("post") %>
<% end %>
</div>
how should the showmsg action would look like so i could show the msg?
thank you very much!
Your controller will need to access the param being sent to it, assign it to an instance variable, which your view will then be able to access.
class HomeController < ApplicationController
def showmsg
#message = params[:p]
end
end
/app/views/home/showmsg.html.erb
...
<%= #message %>
...
I'm using rails 3 and am trying to use the in_place_editing plugin:
http://github.com/wanglian/in_place_editing
# Controller
class BlogController < ApplicationController
in_place_edit_for :post, :title
end
# View
<%= in_place_editor_field :post, 'title' %>
However I'm getting the error: id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
I'm calling the plugin in my photo_album controller, which has a title attribute...
class PhotoAlbumsController < ApplicationController
in_place_edit_for :photo_album, :title
The in the Index View, I'm doing the following:
<% #photoalbums.each do |photoalbum| %>
<%= in_place_editor_field :photoalbum, 'title' %>
<% end %>
Does anyone understand this or have experience with this plugin?
Thanks
The error is because, its trying to update the title of a nil object. You should use this instead
<% #photoalbums.each do |photoalbum| %>
<%= in_place_editor_field photoalbum, 'title' %>
<% end %>
if you see the code of the plugin the definition of the method is
def in_place_editor_field(object, method, tag_options = {}, in_place_editor_options = {})
In case you need to use in_place_editor_field in a loop, do something like this:
Class Item < AR::Base
#attributes like name, price
end
<% for some_item in #items %>
<% #item = some_item %>
<%= in_place_editor_field :item, :price %>
<% end %>