Twitter Integration using Ruby on Rails - ruby-on-rails-3

I have a Ruby on Rails application (Ruby-1.9, Rails-3.2)which integrates with twitter to display the latest tweets containing a particular "keyword" dynamically. But it throws an error as NameError in TweetsController#create uninitialized constant Twitter::Search on the browser .
I have run the db migrations, restarted the server and tried for various options available on the net. But nothing seems to work. Can anyone help to resolve this error ?
The model and controller files are below
Tweet.rb (model file)
class Tweet < ActiveRecord::Base
def self.get_latest_new_year_resolution_tweets(keyword)
search = Twitter::Search.new
search.containing(keyword).result_type("recent").per_page(100).fetch.each do |tweet_results|
twitter_created_at = DateTime.parse(tweet_results.created_at)
unless Tweet.exists?(['twitter_created_at = ? AND from_user_id_str = ?', DateTime.parse(tweet_results.created_at), tweet_results.from_user_id_str])
Tweet.create!({
:from_user => tweet_results.from_user,
:from_user_id_str => tweet_results.from_user_id_str,
:profile_image_url => tweet_results.profile_image_url,
:text => tweet_results.text,
:twitter_created_at => twitter_created_at
})
end
end
end
end
TweetsController
class TweetsController < ApplicationController
def index
end
def create
String strText = params[:tweet][:search].to_s
Tweet.get_latest_new_year_resolution_tweets(strText)
if Tweet.count > 0
Tweet.delete_all
end
Tweet.get_latest_new_year_resolution_tweets(strText)
#tweets = Tweet.order("twitter_created_at desc")
render 'index'
end
end
Index.html.erb (The view file)
<h1>Twitter connect</h1>
<form action="create" method="post">
<label for="keyword">Enter Keyword</label>
<input id="keyword" name="tweet[search]" size="30" type="text" />
<input type="submit" value="search" />
</br> <br>
</form>
</br></br>
<div id="container">
<% if (#tweets != nil && #tweets.count>0) then %>
<ul>
<% #tweets.each do |tweet| %>
<li class="<%=cycle('odd', '')%>">
<%= link_to tweet.from_user, "http://twitter.com/#{tweet.from_user}", :class => "username", :target => "_blank" %>
<div class="tweet_text_area">
<div class="tweet_text">
<%=raw display_content_with_links(tweet.text) %>
</div>
<div class="tweet_created_at">
<%= time_ago_in_words tweet.twitter_created_at %> ago
</div>
</div>
</li>
<% end %>
</ul>
<% end %>
</div>
The gemfile is as below
source 'http://rubygems.org'
gem 'rails', '3.0.3'
gem 'sqlite3', '1.3.6',:group => :development
#gem 'ruby-mysql'
#gem 'mysql2'
group :production do
gem 'pg'
end
gem 'twitter', '4.6.2'

Include below code in your application.rb or top of app/models/tweet.rb files
require 'twitter'
Ex:-
class Tweet < ActiveRecord::Base
require 'twitter'
....
...
end

Related

Comments route in Rails 5.1

I am trying to create Comments on User created Articles in Rails 5.1.
After a Comment is submitted, the redirect should be to the '/articles/:id' but is instead redirecting to '/articles/:id/comments'.
I'm using nested routing in routes.rb:
devise_for :users
root to: "articles#index"
resources :articles do
resources :comments
end
My CommentsController.rb:
class CommentsController < ApplicationController
before_action :set_article
def create
unless current_user
flash[:alert] = "Please sign in or sign up first"
redirect_to new_user_session_path
else
#comment = #article.comments.build(comment_params)
#comment.user = current_user
if #comment.save
flash[:notice] = "Comment has been created"
else
flash.now[:alert] = "Comment not created correctly"
end
redirect_to article_path(#article)
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
def set_article
#article = Article.find(params[:id])
end
end
The form for Comments in articles/show.html.erb:
<!--Start of comments-->
<div class="col-md-12">
<%= form_for [#article, #comment],
:html => {class: "form-horizontal", role: "form"} do
|f| %>
<% if #comment.errors.any? %>
<div class="panel panel-danger col-md-offset-1">
<div class="panel-heading">
<h2 class="panel-title">
<%= pluralize(#comment.error.count, "error") %>
prohibited this comment from being saved:
</h2>
<div class="panel-body">
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
</div>
</div>
<% end %>
<div class="form-group">
<div class="control-label col-md-2">
<%= f.label :body, 'New Comment' %>
</div>
<div class="col-md-10">
<%= f.text_area :body, rows: 10, class: "form-control", placeholder: "New Comment" %>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<%= f.submit "Add Comment", class: "btn btn-primary btn-lg pull-right" %>
</div>
</div>
<% end %>
</div>
How do I make this submit button save and redirect back to 'articles/:id'? Thanks in Advance.
The routes generated by in your router will look something like this:
/articles/:article_id/comments/:id
This means, when you need to load your article in the CommentsController, you should do something like this (as suggested by #Marlin):
def set_article
#article = Article.find(params[:article_id])
end
Otherwise, you run the risk of attaching the comment to the incorrect article if there happens to be an ID collision between the IDs in the comments and article table. Or you simply get a ActiveRecord::RecordNotFound error.
But I know, that this doesn't answer your question directly, ut I suspect that the issue is that you're loading the wrong record from the db somewhere because of the above mentioned.
Try updating your code, and write a test, to make sure that you can programmatically reproduce the error :)

Capybara: Unable to find form field with js: true

I wrote some tests using capybara for request testing using poltergeist and phantomjs as javascript driver.
The following steps for filling in a login form works great without js:
it "signs in" do
visit new_user_session_path
fill_in "Email", with: user
fill_in "Password", with: password||"foobar"
click_button "Login"
end
If I define my test with js it "signs in", js: true do my test fails with error:
Capybara::ElementNotFound: Unable to find field "Email"
The login form itself is built using simple_form as form generator and bootstrap in frontend.
The fields do not have a label. the search text is only contained in the placeholder attribute.
= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
= f.input :email, :placeholder => User.human_attribute_name(:email), :label => false, :input_html => {:class => 'input-xlarge'}
= f.input :password, :placeholder => User.human_attribute_name(:password), :label => false, :input_html => {:class => 'input-xlarge'}
%div
= f.button :submit, "Login", :class => 'btn btn-large btn-primary'
This code generates the following html code
<form accept-charset="UTF-8" action="/users/login" class="simple_form new_user" id="new_user" method="post" novalidate="novalidate">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓">
</div>
<div class="control-group email required user_email">
<div class="controls">
<input class="string email required input-xlarge" id="user_email" name="user[email]" placeholder="Email" size="50" type="email" value="">
</div>
</div>
<div class="control-group password required user_password">
<div class="controls">
<input class="password required input-xlarge" id="user_password" name="user[password]" placeholder="Password" size="50" type="password">
</div>
</div>
<div>
<input class="btn btn btn-large btn-primary" name="commit" type="submit" value="Login">
</div>
</form>
Do you have any Idea how to ensure that the fields are found even if js is activated?
I don't know how your Webrat test passed. In my experience Capybara can't find "Email" if there is no matching Label or id.
In your case, since you don't use label, I suggest you to find the field with id
fill_in "user_email", with user.email
# user_email is the id created by simple_form in general case. Verify yours.
# Don't need "#" before id.
Take a screenshot after visit new_user_session_path and verify html is being rendered when :js => true.
visit new_user_session_path
save_and_open_page
If nothing is being rendered, just an empty html document, make sure in your spec_helper.rb
config.use_transactional_fixtures = false
Also try using DatabaseCleaner gem.
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with :truncation
end
config.before(:each) do
if example.metadata[:js]
DatabaseCleaner.strategy = :truncation
else
DatabaseCleaner.strategy = :transaction
end
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end

Rails Bootstrap Navbar and refineryCMS

Does anyone have implemented the Rails Bootstrap Navbar in refineryCMS?
I'm having a hard time trying to figure out how to render the dropdown menu.
which should be the right way of accomplish this?
_menu.html.erb
<%
if (roots = local_assigns[:roots] || (collection ||= refinery_menu_pages).roots).present?
dom_id ||= 'menu'
css = [(css || 'menu'), 'clearfix'].flatten.join(' ')
hide_children = Refinery::Core.menu_hide_children if hide_children.nil?
-%>
<div class="navbar">
<div class="navbar-inner">
<div class="container">
<nav id='<%= dom_id %>' class='<%= css %> nav'>
<ul class="nav">
<%= render :partial => '/refinery/menu_branch', :collection => roots,
:locals => {
:hide_children => hide_children,
:sibling_count => (roots.length - 1),
:menu_levels => local_assigns[:menu_levels],
:apply_css => true #if you don't care about class='first' class='last' or class='selected' set apply_css to false for speed.
} -%>
</ul>
</nav>
</div>
</div>
</div>
<% end -%>
_menu_branch.html.erb
<%
if !!local_assigns[:apply_css] and (classes = custom_menu_branch_css(local_assigns)).any?
css = "class='#{classes.join(' ')}'".html_safe
end
-%>
<li class="dropdown">
<% if menu_branch.children.present? && menu_branch.ancestors.length < 1 %>
<%= link_to(menu_branch.title, refinery.url_for(menu_branch.url), class: "dropdown-togle", data: { toggle: "dropdown" }) -%>
<% else %>
<%= link_to(menu_branch.title, refinery.url_for(menu_branch.url)) -%>
<% end %>
<% if ( (children = menu_branch.children unless hide_children).present? &&
(!local_assigns[:menu_levels] || menu_branch.ancestors.length < local_assigns[:menu_levels]) ) -%>
<ul class="dropdown-menu">
<%= render :partial => '/refinery/menu_branch', :collection => children,
:locals => {
:apply_css => local_assigns[:apply_css],
:hide_children => !!hide_children,
:menu_levels => local_assigns[:menu_levels]
} -%>
</ul>
</li>
<% end -%>
nav_bar snippet
<%= nav_bar :fixed => :top, :brand => "Fashionable Clicheizr 2.0", :responsive => true do %>
<%= menu_group do %>
<%= menu_item "Home", root_path %>
<%= menu_divider %>
<%= drop_down "Products" do %>
<%= menu_item "Things you can't afford", expensive_products_path %>
<%= menu_item "Things that won't suit you anyway", harem_pants_path %>
<%= menu_item "Things you're not even cool enough to buy anyway", hipster_products_path %>
<% if current_user.lives_in_hackney? %>
<%= menu_item "Bikes", fixed_wheel_bikes_path %>
<% end %>
<% end %>
<%= menu_item "About Us", about_us_path %>
<%= menu_item "Contact", contact_path %>
<% end %>
<%= menu_group :pull => :right do %>
<% if current_user %>
<%= menu_item "Log Out", log_out_path %>
<% else %>
<%= form_for #user, :url => session_path(:user), html => {:class=> "navbar-form pull-right"} do |f| -%>
<p><%= f.text_field :email %></p>
<p><%= f.password_field :password %></p>
<p><%= f.submit "Sign in" %></p>
<% end -%>
<% end %>
<% end %>
<% end %>
Faced for some hours with same issue.
Have solution with bit more pretty code (or just more close to refinery standarts), I believe, its better to override base Refinery menu_presenter
first of all take a look a bit simmilar quest http://refinerycms.com/guides/menu-presenter and this one too: http://refinerycms.com/guides/extending-controllers-with-decorators
So. Based on that article lets do this
app/decorators/models/refinery/page_decorator.rb:
Refinery::Page.class_eval do
def self.menu_pages
where :show_in_menu => true
end
end
app/helpers/application_helper.rb
module ApplicationHelper
def menu_header
menu_items = Refinery::Menu.new(Refinery::Page.menu_pages)
presenter = Refinery::Pages::MenuPresenter.new(menu_items, self)
presenter.first_css = nil
presenter.last_css = nil
presenter
end
end
in terminal run:
cd /path/to/app/
rake refinery:override presenter=refinery/pages/menu_presenter
It will generate app/presenters/refinery/pages/menu_presenter.rb change it to this:
require 'active_support/core_ext/string'
require 'active_support/configurable'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/url_helper'
module Refinery
module Pages
class MenuPresenter
include ActionView::Helpers::TagHelper
include ActionView::Helpers::UrlHelper
include ActiveSupport::Configurable
config_accessor :roots, :menu_tag, :list_tag, :list_item_tag, :css, :dom_id,
:max_depth, :selected_css, :first_css, :last_css, :list_first_css,
:list_dropdown_css, :list_item_dropdown_css,
:list_item__css, :link_dropdown_options, :carret
self.dom_id = :div
self.css = ["nav-collapse", "collapse", "navbar-responsive-collapse"]
self.menu_tag = :nav
self.list_tag = :ul
self.list_first_css = :nav
self.carret = '<b class="caret"></b>'
self.list_dropdown_css = "dropdown-menu"
self.link_dropdown_options = {class: "toggle-dropdown", data: {:toggle=>"dropdown"}}
self.list_item_tag = :li
self.list_item_dropdown_css = :dropdown
self.list_item__css = nil
self.selected_css = :active
self.first_css = :first
self.last_css = :last
def roots
config.roots.presence || collection.roots
end
attr_accessor :context, :collection
delegate :output_buffer, :output_buffer=, :to => :context
def initialize(collection, context)
#collection = collection
#context = context
end
def to_html
render_menu(roots) if roots.present?
end
private
def render_menu(items)
content_tag(menu_tag, :id => dom_id, :class => css) do
render_menu_items(items)
end
end
def render_menu_items(menu_items)
if menu_items.present?
content_tag(list_tag, :class => menu_items_css(menu_items)) do
menu_items.each_with_index.inject(ActiveSupport::SafeBuffer.new) do |buffer, (item, index)|
buffer << render_menu_item(item, index)
end
end
end
end
def render_menu_item(menu_item, index)
content_tag(list_item_tag, :class => menu_item_css(menu_item, index)) do
#cont = context.refinery.url_for(menu_item.url)
buffer = ActiveSupport::SafeBuffer.new
if check_for_dropdown_item(menu_item)
buffer << link_to((menu_item.title+carret).html_safe, "#", link_dropdown_options)
else
buffer << link_to(menu_item.title, context.refinery.url_for(menu_item.url))
end
buffer << render_menu_items(menu_item_children(menu_item))
buffer
end
end
def check_for_dropdown_item(menu_item)
(menu_item!=roots.first)&&(menu_item_children(menu_item).count > 0)
end
# Determines whether any item underneath the supplied item is the current item according to rails.
# Just calls selected_item? for each descendant of the supplied item
# unless it first quickly determines that there are no descendants.
def descendant_item_selected?(item)
item.has_children? && item.descendants.any?(&method(:selected_item?))
end
def selected_item_or_descendant_item_selected?(item)
selected_item?(item) || descendant_item_selected?(item)
end
# Determine whether the supplied item is the currently open item according to Refinery.
def selected_item?(item)
path = context.request.path
path = path.force_encoding('utf-8') if path.respond_to?(:force_encoding)
# Ensure we match the path without the locale, if present.
if %r{^/#{::I18n.locale}/} === path
path = path.split(%r{^/#{::I18n.locale}}).last.presence || "/"
end
# First try to match against a "menu match" value, if available.
return true if item.try(:menu_match).present? && path =~ Regexp.new(item.menu_match)
# Find the first url that is a string.
url = [item.url]
url << ['', item.url[:path]].compact.flatten.join('/') if item.url.respond_to?(:keys)
url = url.last.match(%r{^/#{::I18n.locale.to_s}(/.*)}) ? $1 : url.detect{|u| u.is_a?(String)}
# Now use all possible vectors to try to find a valid match
[path, URI.decode(path)].include?(url) || path == "/#{item.original_id}"
end
def menu_items_css(menu_items)
css = []
css << list_first_css if (roots == menu_items)
css << list_dropdown_css if (roots != menu_items)
css.reject(&:blank?).presence
end
def menu_item_css(menu_item, index)
css = []
css << list_item_dropdown_css if (check_for_dropdown_item(menu_item))
css << selected_css if selected_item_or_descendant_item_selected?(menu_item)
css << first_css if index == 0
css << last_css if index == menu_item.shown_siblings.length
css.reject(&:blank?).presence
end
def menu_item_children(menu_item)
within_max_depth?(menu_item) ? menu_item.children : []
end
def within_max_depth?(menu_item)
!max_depth || menu_item.depth < max_depth
end
end
end
end
almost done. add menu_header.to_html to your menu inside container of your menu like this:
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="#"><%=Refinery::Core::site_name %></a>
<%= menu_header.to_html %>
</div>
</div>
</div>
PS: RefineryCMS 2.1.0
Refinery 2.1.0 with Bootstrap 3
None of the solutions above worked for me. So I had to adapt from Valentine Konov's answer. Below you can find all of my files. You can always leave me a comment if you need any help. Here we go!
1) Check your RefineryCMS and Bootstrap versions
Gemfile
gem 'bootstrap-sass', '~> 3.1.1'
gem 'refinerycms', '~> 2.1.0'
2) Save a few lines of code
a. You actually have no need to create an app/decorators/models/refinery/page_decorator.rb file.
b. You can forget the menu_header method as well. This way, you'll have:
app/helpers/application_helper.rb
module ApplicationHelper
end
3) Now let's get to the real work
a. Override your default header with:
$ rake refinery:override view=refinery/_header.html
And change its code to:
app/views/refinery/_header.html.erb
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#"><%=Refinery::Core::site_name %></a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<%= Refinery::Pages::MenuPresenter.new(refinery_menu_pages, self).to_html %>
</div>
</div>
</nav>
b. Now go to terminal and run rake refinery:override presenter=refinery/pages/menu_presenter. It will generate a menu_presenter.rb file. Change it to this:
app/presenters/refinery/pages/menu_presenter.rb
require 'active_support/core_ext/string'
require 'active_support/configurable'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/url_helper'
module Refinery
module Pages
class MenuPresenter
include ActionView::Helpers::TagHelper
include ActionView::Helpers::UrlHelper
include ActiveSupport::Configurable
config_accessor :roots, :menu_tag, :list_tag, :list_item_tag, :css, :dom_id,
:max_depth, :selected_css, :first_css, :last_css, :list_first_css,
:list_dropdown_css, :list_item_dropdown_css,
:list_item__css, :link_dropdown_options, :carret
# self.dom_id = nil
# self.css = "pull-left"
self.menu_tag = :section
self.list_tag = :ul
self.list_first_css = ["nav", "navbar-nav", "navbar-right"]
self.carret = '<b class="caret"></b>'
self.list_dropdown_css = "dropdown-menu"
self.link_dropdown_options = {class: "dropdown-toggle", data: {:toggle=>"dropdown"}}
self.list_item_tag = :li
self.list_item_dropdown_css = :dropdown
self.list_item__css = nil
self.selected_css = :active
self.first_css = :first
self.last_css = :last
def roots
config.roots.presence || collection.roots
end
attr_accessor :context, :collection
delegate :output_buffer, :output_buffer=, :to => :context
def initialize(collection, context)
#collection = collection
#context = context
end
def to_html
render_menu(roots) if roots.present?
end
private
def render_menu(items)
content_tag(menu_tag, :id => dom_id, :class => css) do
render_menu_items(items)
end
end
def render_menu_items(menu_items)
if menu_items.present?
content_tag(list_tag, :class => menu_items_css(menu_items)) do
menu_items.each_with_index.inject(ActiveSupport::SafeBuffer.new) do |buffer, (item, index)|
buffer << render_menu_item(item, index)
end
end
end
end
def render_menu_item(menu_item, index)
content_tag(list_item_tag, :class => menu_item_css(menu_item, index)) do
#cont = context.refinery.url_for(menu_item.url)
buffer = ActiveSupport::SafeBuffer.new
if check_for_dropdown_item(menu_item)
buffer << link_to((menu_item.title+carret).html_safe, "#", link_dropdown_options)
else
buffer << link_to(menu_item.title, context.refinery.url_for(menu_item.url))
end
buffer << render_menu_items(menu_item_children(menu_item))
buffer
end
end
def check_for_dropdown_item(menu_item)
(menu_item!=roots.first)&&(menu_item_children(menu_item).count > 0)
end
# Determines whether any item underneath the supplied item is the current item according to rails.
# Just calls selected_item? for each descendant of the supplied item
# unless it first quickly determines that there are no descendants.
def descendant_item_selected?(item)
item.has_children? && item.descendants.any?(&method(:selected_item?))
end
def selected_item_or_descendant_item_selected?(item)
selected_item?(item) || descendant_item_selected?(item)
end
# Determine whether the supplied item is the currently open item according to Refinery.
def selected_item?(item)
path = context.request.path
path = path.force_encoding('utf-8') if path.respond_to?(:force_encoding)
# Ensure we match the path without the locale, if present.
if %r{^/#{::I18n.locale}/} === path
path = path.split(%r{^/#{::I18n.locale}}).last.presence || "/"
end
# First try to match against a "menu match" value, if available.
return true if item.try(:menu_match).present? && path =~ Regexp.new(item.menu_match)
# Find the first url that is a string.
url = [item.url]
url << ['', item.url[:path]].compact.flatten.join('/') if item.url.respond_to?(:keys)
url = url.last.match(%r{^/#{::I18n.locale.to_s}(/.*)}) ? $1 : url.detect{|u| u.is_a?(String)}
# Now use all possible vectors to try to find a valid match
[path, URI.decode(path)].include?(url) || path == "/#{item.original_id}"
end
def menu_items_css(menu_items)
css = []
css << list_first_css if (roots == menu_items)
css << list_dropdown_css if (roots != menu_items)
css.reject(&:blank?).presence
end
def menu_item_css(menu_item, index)
css = []
css << list_item_dropdown_css if (check_for_dropdown_item(menu_item))
css << selected_css if selected_item_or_descendant_item_selected?(menu_item)
css << first_css if index == 0
css << last_css if index == menu_item.shown_siblings.length
css.reject(&:blank?).presence
end
def menu_item_children(menu_item)
within_max_depth?(menu_item) ? menu_item.children : []
end
def within_max_depth?(menu_item)
!max_depth || menu_item.depth < max_depth
end
end
end
end
c. Restart your server and see the results. If you already have some pages created, your navbar should look similar to the one below:
Try this _menu_branch.html.erb
<% if ( (children = menu_branch.children unless hide_children).present? &&
(!local_assigns[:menu_levels] || menu_branch.ancestors.length < local_assigns[:menu_levels]) ) -%>
<%
if !!local_assigns[:apply_css] and (classes = menu_branch_css(local_assigns)).any?
css = "class='#{classes.join(' ')} dropdown'".html_safe
end
-%>
<li<%= ['', css].compact.join(' ').gsub(/\ *$/, '').html_safe %>>
<%= link_to("#{menu_branch.title} <b class='caret'></b>".html_safe, refinery.url_for(menu_branch.url), :class=>"dropdown-toggle", 'data-toggle'=>'dropdown') -%>
<ul class='dropdown-menu'>
<%= render :partial => '/refinery/menu_branch', :collection => children,
:locals => {
:apply_css => local_assigns[:apply_css],
:hide_children => !!hide_children,
:menu_levels => local_assigns[:menu_levels]
} -%>
</ul>
</li>
<% else -%>
<%
if !!local_assigns[:apply_css] and (classes = menu_branch_css(local_assigns)).any?
css = "class='#{classes.join(' ')}'".html_safe
end
-%>
<li<%= ['', css].compact.join(' ').gsub(/\ *$/, '').html_safe %>>
<%= link_to(menu_branch.title, refinery.url_for(menu_branch.url)) -%>
</li>
<% end -%>
_menu.html.erb
<%
# Collect the root items.
# ::Refinery::Menu is smart enough to remember all of the items in the original collection.
if (roots = local_assigns[:roots] || (collection ||= refinery_menu_pages).roots).present?
dom_id ||= 'menu'
css = [(css || 'menu clearfix')].flatten.join(' ')
hide_children = Refinery::Core.menu_hide_children if hide_children.nil?
-%>
<div id="main-menu" class="nav-collapse">
<nav id='<%= dom_id %>' class='<%= css %>'>
<ul id="main-menu-left" class="nav">
<%= render :partial => '/refinery/menu_branch', :collection => roots,
:locals => {
:hide_children => hide_children,
:sibling_count => (roots.length - 1),
:menu_levels => local_assigns[:menu_levels],
:apply_css => true #if you don't care about class='first' class='last' or class='selected' set apply_css to false for speed.
} -%>
</ul>
</nav>
</div>
<% end -%>
and _header.html.erb
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<div class="container">
<a data-target=".nav-collapse" data-toggle="collapse" class="btn btn-navbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<%= link_to Refinery::Core.site_name, refinery.root_path, :class => "brand" %>
<%= render(:partial => "/refinery/menu", :locals => {
:dom_id => 'menu',
:css => 'menu'
}) %>
</div>
</div>
</div>
</div>
The approach outlined by user1852788 worked for me. If you are using a menu with drop downs don't forget to load the bootstrap js in your application.js manifest file:
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .
And then call the dropdown function (I have a file called layout.js.coffee):
$('.dropdown-toggle').dropdown()
This Gist worked great for me for the latest of Refinery and Bootstrap https://gist.github.com/npflood/2d3f5fc44518ef231195
There is a gem that tries to solve this problem.
https://github.com/ghoppe/refinerycms-bootstrap
But I've been having problems with it personally.
I found much easier way to do this for refinerycms 2-0-stable
my solution is the following:
first _menu.html.erb update css variable with bootstrap classes and add necessary html for example I added div to wrap ul
<%
# Collect the root items.
# ::Refinery::Menu is smart enough to remember all of the items in the original collection.
if (roots = local_assigns[:roots] || (collection ||= refinery_menu_pages).roots).present?
dom_id ||= 'menu'
css = [(css || 'pull-right')].flatten.join(' ')
hide_children = Refinery::Core.menu_hide_children if hide_children.nil?
-%>
<nav id='<%= dom_id %>' class='<%= css %>'>
<div class="collapse navbar-collapse">
<ul class="nav nav-pills navbar-nav">
<%= render :partial => '/refinery/menu_branch', :collection => roots,
:locals => {
:hide_children => hide_children,
:sibling_count => (roots.length - 1),
:menu_levels => local_assigns[:menu_levels],
:apply_css => true #if you don't care about class='first' class='last' or class='selected' set apply_css to false for speed.
} -%>
</ul>
</div>
</nav>
<% end -%>
second _menu_branch.html.erb update class with bootstrap classes
<%
if !!local_assigns[:apply_css] and (classes = menu_branch_css(local_assigns)).any?
css = "class='#{classes.join(' ')}'".html_safe
end
-%>
<% if ( (children = menu_branch.children unless hide_children).present? &&
(!local_assigns[:menu_levels] || menu_branch.ancestors.length < local_assigns[:menu_levels]) ) -%>
<li class="dropdown">
<%= menu_branch.title %><b class="caret"></b>
<ul class='dropdown-menu'>
<%= render :partial => '/refinery/menu_branch', :collection => children,
:locals => {
:apply_css => local_assigns[:apply_css],
:hide_children => !!hide_children,
:menu_levels => local_assigns[:menu_levels]
} -%>
</ul>
<% else -%>
<li<%= ['', css].compact.join(' ').gsub(/\ *$/, '').html_safe %>>
<%= link_to(menu_branch.title, refinery.url_for(menu_branch.url)) -%>
<% end -%>
</li>
now your menu should display fine. To enable Active you just need to update /config/initializers/refinery/core.rb file by changing the following code:
change selected, to active
# CSS class selectors for menu helper
config.menu_css = {:selected=>"active", :first=>"first", :last=>"last"}

fields_for not rendering association name (belongs_to relationship)

I'm trying to create the form to create an event. Events belong_to a creator (of class user), and the form includes fields_for the creator.
Largely the form is working - it renders everything else properly, and the create action processes it properly when the fields_for #event.creator section is commented out. The fields_for tag is rendering event[user] tags instead of event[creator], though, and i can't figure out why. Ideas? Here are the relevant excerpts.
(in views/events/new.html.erb)
<%= form_for #event do |form| %>
<%= render :partial => '/events/form', :object => form %>
<%= form.submit 'Go!' %>
<% end %>
(in events/_form.html.erb)
...
<% if !signed_in? %>
To create your event, please provide an email address and create a password. <br />
<%= form.fields_for #event.creator do |uf| %>
<div class="email_field">
<%= uf.label :email %>
<%= uf.text_field :email, :type => "email" %>
</div>
...
<% end %>
<% end %>
(controllers/events_controller.rb)
def new
#event = Event.new
if !signed_in?
#event.build_creator
end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #event }
end
end
(models/event.rb)
belongs_to :creator, :class_name => "User"
accepts_nested_attributes_for :creator
Largely this works, but the form elements render as
<div class="email_field">
<label for="event_user_email">Email</label>
<input id="event_user_email" name="event[user][email]" size="30" type="email" />
</div>
<div class="password_field">
<label for="event_user_password">Password</label>
<input id="event_user_password" name="event[user][password]" size="30" type="password" />
</div>
...
the issue here is event_user and event[user] instead of event_creator and event[creator]; when i submit the form i get an error that event doesn't have a User field.
<%= form.fields_for :creator, #event.creator do |uf| %>

rails 3 Admin Authentication

Whats wrong in my authentication i also dont know..can someone tell me what wrong?
i got user scaffold, and this is my admin controller
class AdminController < ApplicationController
def login
if request.post?
user = User.authenticate(params[:name], params[:password])
if user
session[:user_id] = user.id
redirect_to(:action => "index")
else
flash.now[:notice] = "Invalid user/password combination"
end
end
end
def logout
session[:user_id] = nil
flash[:notice] = "Logged out"
redirect_to(:action => "login")
end
def index
end
end
and this is my admin/login.html.erb
<div>
<%= form_tag do %>
<fieldset>
<legend>Please Log In</legend>
<div>
<label for="name">Name:</label>
<%= text_field_tag :name, params[:name] %>
</div>
<div>
<label for="password">Password:</label>
<%= password_field_tag :password, params[:password] %>
</div>
<div>
<%= submit_tag "Login" %>
</div>
</fieldset>
<% end %>
</div>
but when i try to log in using existence user it come like this
No route matches "/admin/login"
whats wrong with my code??am i missing something?
You should do that
Hawary::Application.routes.draw do
post 'admin/login' => 'admin#login'
end