Ransack search form for nested model in Rails 3 app - ruby-on-rails-3

I want to search and return an index of Users based on their Profile data using Ransack in my Rails 3 app. In the docs it mentions nested attributes but since I'm a beginner I'm not sure how to use the helpers to accomplish what I want.
The ransack docs recommend the following:
users_controller.rb:
def index
#q = User.search(params[:q])
#users = #q.result(:distinct => true)
end
def search
index
render :index
end
routes.rb:
resources :users do
collection do
match 'search' => 'users#search', :via => [:get, :post], :as => :search
end
end
app/views/users/index.html.erb:
<%= search_form_for #q, :url => search_users_path,
:html => {:method => :post} do |f| %>
<% end %>
In the form I've tried to weave in the profile by using:
<%= current_user.profile.high_school %>
<%= f.text_field :profile_high_school_cont %>
Doing this doesn't work, however. The results show nothing when I search for a field belonging to at least one User's profile.

Actually, this does work. I had a f.check_box that was messing things up.

Related

condition in partial from other controller

I have a model group -> has_many :questions and a question -> has_many :votes
In my my view show, for the controller groups, I have a partial that can display the list of the questions :
<%= render :partial => 'question', :collection => #group.questions.byvote %>
Then I have a link to vote with a style like this :
<%= link_to(question_votes_path(question), :controller => :vote, :action => :create, :method => :post, :id => 'vote') do %>
<%= image_tag("voteUp.png")%>
<%= question.votes_count%>
<%end%>
What I would like to do is make a condition, like :
<% if canvote?%>
… and change the style of the div.
BUT. Making a condition in the group controller can't be made because I need to make my request about the question and not about the group :
Vote.where(:user_id => current_user.id, :question_id => #question.id).first
How can I make it form the other controller group or tell an helper_method in the question controller ?
I think you should use a model method - you can then call it right in the view and do so unobtrusively. The following method will return true if the user has voted on a given question:
User.rb
def voted?(question)
#returns true if vote exists
Vote.exists?(:user_id => current_user.id, :question_id => question.id)
end
You can use it like this:
_question.html.erb
<% if current_user.voted?(#question) %>
#code to use if the user has voted on this question
<% else %>
#code to use if the user has NOT voted on this question
<% end %>

Memory (hex) address being returned instead of value in Rails

I'm definitely a bit of a noob, so this might be something simple that I'm overlooking, however, the searches that I've done to try and find a solution have come up empty.
I've built a form using formtastic that has 5 input fields: two are text boxes and three are select lists.
<%= semantic_form_for #player do |f| %>
<%= f.inputs do %>
<%= f.input :firstname, :label => "First Name " %>
<%= f.input :lastname, :label => "Last Name " %>
<%= f.input :leagueid, :as => :select, :collection => League.all(:order => :leaguename), :label => "League " %>
<%= f.input :team_1, :as => :select, :collection => Team.all(:order => :name), :label => "Team 1 " %>
<%= f.input :team_2, :as => :select, :collection => Team.all(:order => :name), :label => "Team 1 " %>
<% end %>
<%= f.actions %>
<% end %>
What is happening is that the Teams lists work perfectly (the team names are displayed). However, the League list is a different story. All of the entries in the list look like this (with different a different code after 'League:'):
#<League:0x007fe29c406498>
If I use the form to create a Player, it works fine. The correct league ID goes into the database and everything. I just can't figure out why the names of the teams show, while whatever-that-is shows for the league.
Any and all help is appreciated.
When converting objects to String, Ruby will convert them to the memory address like you see unless you provide a to_s method for string conversions. I haven't used formtastic, but I believe adding a to_s method to your League class should cause it to display what you want.
Try adding
def to_s
#name # use whatever you want to be displayed.
end
to the League class.
You could try explicitly specifying the fields that should be used as the text and id within the select list. I believe it would look like.
<%= f.input :leagueid, :as => :select, :collection => Hash[League.all.map { |league| [league.leaguename, league.id] }]
The syntax is crazy. The call to map is returning an array of name/id pairs, like [ ['league1', 1], ['league2', 2] ]. Calling Hash on that converts it to a hash, like {'league1' => 1, 'league2' => 2}. Seems like the select list should use this hash to populate itself.
There's an example of this at http://rdoc.info/github/justinfrench/formtastic, under the Usage section.
:member_name is the solution I think.
<%= f.input :leagueid, :as => :select, :collection => League.all(:order => :leaguename), :label => "League " %>
Will probably work for you as
<%= f.input :leagueid, :as => :select, :member_name => :league, :collection => League.all(:order => :leaguename), :label => "League " %>
My problem was I have a model with a field the same name as the model and I think that confused Formtastic
Example scaffold:
rails g scaffold Countries code:string country:string
rails g scaffold Types title:string description:string
Model:
class Sign < ActiveRecord::Base
attr_accessible :title, :country_id, :type_id
belongs_to :country
belongs_to :type
Form View:
<%= f.input :type %>
<%= f.input :country, :member_label => :country %>
Having a form without the member_label leads to the object id displaying in the select box for countries although the ID is correctly saved. The type select worked perfectly without declaring member_label.
Note that I didn't need to specify :as => :select as formtastic can deduce this from the belongs_to relationship.
Try using :
<%= form.input :league, :member_label => :leaguename %>
This will override the naming convention of the Formtastic Column Select.
Have a look also at : Overriding the Column Name Convention wiki
Hope this helped.

Rails passing local parameters through link_to into js then load in partial

I am trying to pass along a local variable to a partial using link_to. I have tried many different things, but it doesn't seem to work. The js file loads the partial fine, it just doesn't have the locals. This is what I have, thanks for any direction!
_health.html.erb (this is a partial on index.html of Contacts model)
<% #comments = Comment.find_all_by_api(#api) %>
<%= link_to 'Read Comments', comments_path(:comments => #comments), :action => 'comments', :remote => true %>
comments.js.erb
$("#comments").html("<%= escape_javascript(render(:partial => 'comment', :locals => {:comments => :comments})) %>");
comment.html.erb
<% unless #comments.blank? %>
<% #comments.each do |c| %>
<%= c %><br />
<% end %>
<% end %>
contacts_controller.rb
def comments
respond_to do | format |
format.js {render :layout => false}
end
end
The partial does not know about the comments because you never set them. The comments action in the controller needs to look like this:
def comments
#comments = Comment.find(params[:id])
respond_to do | format |
(replace params[:id] with the appropriate parameter from your route)
You're doing an AJAX request and since http is stateless, the comments action does not know anything about any previous requests - which means that the comments from _health.html.erb have ceased to exist for the comments action in the controller.

Rails appends id to singular route when render edit after errors

I have the following singular route:
scope '/seller' do
resource :seller_profile, :path => "/profile", :only => [:show, :edit, :update]
end
and the following controller:
class SellerProfilesController < ApplicationController
before_filter :validate_user_as_seller
def show
#seller_profile = current_user.seller_profile
end
def edit
#seller_profile = current_user.seller_profile
end
def update
#seller_profile = current_user.seller_profile
if #seller_profile.update_attributes(params[:seller_profile])
redirect_to(seller_profile_path, :notice => 'Profile was successfully updated.')
else
render :action => "edit"
end
end
end
I use a singular route given that the user must be authenticated before gaining access to the controller and therefore I can get the seller_profile from the user logged in.
This works like a charm, with only one problem. When I edit the seller_profile and validation error happen, the form is edited again and the errors are displayed correctly. The problem is that rails appends to the url the id of the edited record. For instance,
when I first edit the record, the url is:
http://0.0.0.0:3000/seller/profile/edit
but if the form is submitted with validation errors, the form itself is redisplayed under
http://0.0.0.0:3000/seller/profile.2
where 2 is the ID of the record being edited.
The form is the following:
<%= simple_form_for #seller_profile do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.submit %>
<% end %>
Everything, as said, works great but I would totally mask the ID in the url. What should I do?
I have not really worked too much with simple_form_for. But it looks like it is guessing your url always as if they were not single resources. You can provide a custom one:
<%= simple_form_for #seller_profile, :url => seller_profile_path do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.submit %>
<% end %>

In Rails 3, using Formtastic and Devise, generic routes producing errors when adding a new entry for a model

I have a very simple rails 3 program with 2 models: a user model for Devise and a writing model that captures a text field and the user's id.
My routes file is pretty basic:
devise_for :users
resources :users, :writings
root :to => "users#index"
And my form for writings, using Formtastic, is as well:
<% semantic_form_for(#writing, :html => {:method => :put}) do |f| %>
<%= f.input :main %>
<%= f.input :user_id, :collection => current_user, :as => :hidden %>
<%= f.buttons %>
<% end %>
When I try to create a new writing, the form looks great, but then when I hit submit, I get the following error:
No route matches "/writings"
I've run rake routes, and everything else seems to be working on, and I am using the default generate scaffold from rails, so the controller is the out of the box controller.
Any ideas on where I went astray?
Chris, try putting the declaration of the form like this
<% semantic_form_for #writing do |f| %>
<%= f.input :main %>
<%= f.input :user_id, :collection => current_user, :as => :hidden %>
<%= f.buttons %>
<% end %>
I've the idea that when you specify the :html parameter, you "override" some defaults in formtastic. Sorry, I'm not an expert on formtastic. I've used a bit and then decided to go for simple_form :).