Showing posts with label rubyonrails. Show all posts
Showing posts with label rubyonrails. Show all posts

April 01, 2015

Omniauth With Facebook in Rails app - Simple demo

Posted by Unknown
0

Create a new rails application

# rails new sample_app

Open Gemfile and add following line into

gem 'omniauth'
gem 'omniauth-facebook'
Then run command to install it.
# bundle install

Create a provider

https://developers.facebook.com/

Go to My Apps and create a new app, copy App's ID and secret.

Configure

Configure your app to alive status

In config/initializers create omniauth.rb file

Add following lines
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, 'YOUR_APP_ID', 'YOUR_APP_SECRET'
end

Create login page

# rails g controller sessions new create

Open config/routes.rb

get   '/login', :to => 'sessions#new' => :login
get '/auth/:provider/callback' => 'sessions#create'

Open your app/controllers/sessions_controller.rb file and write the create method, like this:

def create
  auth_hash = request.env['omniauth.auth']
 
  render :text => auth_hash.inspect
end
Then you open browser and point to http://localhost:3000/auth/facebook, you can see some info of your facebook account.

Create a user model

# rails g model User name:string email:string
# rails generate model Authorization provider:string uid:string user_id:integer

Add the following code to your app/models/user.rb file:

has_many :authorizations
validates :name, :email, :presence => true

Add the following code to your app/models/authorization.rb file:

belongs_to :user
validates :provider, :uid, :presence => true

Modified create function in sessions_controller.rb

def create
  auth_hash = request.env['omniauth.auth']
 
  @authorization = Authorization.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"])
  if @authorization
    render :text => "Welcome back #{@authorization.user.name}! You have already signed up."
  else
    user = User.new :name => auth_hash["info"]["name"], :email => auth_hash["info"]["email"]
    user.authorizations.build :provider => auth_hash["provider"], :uid => auth_hash["uid"]
    user.save
 
    render :text => "Hi #{user.name}! You've signed up."
  end
end
Go back, refresh web app. You can see your name !

Create destroy function to logout

Open sessions_controller.rb and add function:
def destroy
  session[:user_id] = nil
  render :text => "You've logged out!"
end
Open routes.rb, add route:
get '/logout' => 'sessions#destroy'


Pretty URL in Rails 4 - Build a Simple Application

Posted by Unknown
0

Install gem stringex

Add following lines to Gemfile
gem 'stringex', '~> 2.5.2'
gem 'responders'
Run command
# bundle install

Rails application have model Post with id:integer and title:string

class Post < ActiveRecord::Base
  acts_as_url :title, url_attribute: :slug
 
  def to_param
    "#{id}-#{slug}"
  end
end

With config above, example: I have a post with id = 1 and title = "This is an example" then link to post look like

http://localhost:3000/posts/1-this-is-an-example



Nested Attributes in Rails 4 - Nested Model Form

Posted by Unknown
0

If you have models: Survey has many Questions and Question has many anwsers.

Your models

models/survey.rb

class Survey < ActiveRecord::Base
  has_many :questions, :dependent => :destroy
  accepts_nested_attributes_for :questions, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end

models/question.rb

class Question < ActiveRecord::Base
  belongs_to :survey
  has_many :answers, :dependent => :destroy
  accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end

models/answer.rb

class Answer < ActiveRecord::Base
  belongs_to :question
end

Your controllers

survey_controller.rb

def new
  @survey = Survey.new
  3.times do
    question = @survey.questions.build
    4.times { question.answers.build }
  end
end
The new method above will create survey with 3 questions and 4 answer for each question.

create method in survey_controller.rb

  def create
    @survey = Survey.new survey_params
    if @survey.save
      flash[:success] = "New survey has been created!"
      redirect_to surveys_path
    else
      render 'new'
    end
  end

Strong params in rails 4

# in survey_controller.rb

private

def survey_params
  params.require(:survey).permit :name, questions_attributes: [:content, :name, answers_attributes: [:content]]
end
* Change these attributes to correct your app.

Your view files

views/surveys/new.html.erb

<%= form_for @survey do |f| %>
  <%= f.error_messages %>
  <%= f.label :name %>
  <%= f.text_field :name %>

  <%= f.fields_for :questions do |builder| %>
    <%= render "question_fields", :f => builder %>
  <% end %>
  <%= f.submit "Submit" %>

<% end %>

views/surveys/question_fields.html.erb

<%= f.label :content, "Question" %>

  <%= f.text_area :content, :rows => 3 %>

  <%= f.check_box :_destroy %>
  <%= f.label :_destroy, "Remove Question" %>



<%= f.fields_for :answers do |builder| %>
  <%= render 'answer_fields', :f => builder %>
<% end %>

views/surveys/answer_fields.html.erb

<%= f.label :content, "Answer" %>
  <%= f.text_field :content %>
  <%= f.check_box :_destroy %>
  <%= f.label :_destroy, "Remove" %>





March 04, 2015

Bootstrap Typeahead on Rails App - Typeahead and Gon

Posted by Unknown
0

Try example at : Demo Typeahead

Add Gemfile

gem 'bootstrap-typeahead-rails', '~> 0.10.5.1'
Run command to install gem
$ bundle install

Add gon Gem

gem 'gon'
$ bundle install

Add following line to application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>TenderMessenger</title>
    <%= include_gon %>
      ...other scripts, etc.
  </head>

Add Gon to your controllers. The idea is to assign your Rails variable to a Gon variable (which will become a JavaScript variable). In my case, trying to pass users’ names and images, it looked like this:

def index
  gon.usernames = User.pluck(:name)
  gon.gravatars = User.all.map { |user| user.gravatar }
  # ...other code that belongs in the controller action
end

You can assign any array to the Gon variable. Both of my examples return arrays by calling methods (ActiveRecord query for usernames and mapping image links), but you could just as easily do gon.variable = [example1, example2, example3] (though, as we’ll see, you could add this data straight into your JavaScript file)

Assign that Gon variable to a JavaScript variable. In whatever .js file you choose, assign

// Other javascript...
var gravatars = gon.gravatars
var usernames = gon.usernames;
// More javascript

Open application.js

//= require twitter/typeahead
Determine the css selector for the input on which you want to implement typeahead. In my case, I added a class of “typeahead” to my targeted text field as follows:
<!-- ...preceding html/erb... -->
<%= text_field_tag :name_or_email, nil, placeholder: "To: name or email", class: "typeahead" %> 
<!-- ... -->
 
  • In whichever JavaScript file you’ve made the dataset available, add $('.typeahead').typeahead(). Replace “.typeahead” with whatever CSS selector you’re using (see previous step). You now have the entire structure into which you can try the various typeahead.js examples.
     
  • I started with the basics, copying line 1-23 above my typeahead method, and everything withing the curly braces from line 37-44 into my typeahead method. Make sure to change the example’s default variable (“states” in the basic example, “best-pictures” in the custom templates example) to whatever variable you assigned using Gon. Depending on how your Rails app is structured–particularly what your asset pipeline looks like–this may be all you need.
  • I had conflicting stylesheets and JavaScript files, plus I wanted more flexibility creating templates for the typeahead, so I implemented the custom templates example. Full code for what I describe is below.
To begin, I added the templates (lines 28-40). The “empty” template worked easily–the code copied from Twitter’s example worked on its own. I had more difficulty with the “suggestion” template, primarily because I didn’t immediately realize that it’s a function, as opposed to the string that the “empty” template was. At this point, I was able to style the template as I liked, even including an image. pattern of passing entire objects and calling two or more different attributes (best pictures’ names and years in the custom template example), but I was unable to configure my JavaScript this way. Instead, knowing that my “gravatars” array directly mirrored my “usernames”, I used JavaScript’s indexOf() method, as seen in line 37. This enabled me to the the index of a given username and find the gravatar url at that index of the gravatars array. Not ideal, but it worked.
// Twitter Typeahead
$(document).ready(function() {
  var substringMatcher = function(strs) {
    return function findMatches(q, cb) {
      var matches, substringRegex;
      matches = [];
      substrRegex = new RegExp(q, 'i');
      $.each(strs, function(i, str) {
        if (substrRegex.test(str)) {
          matches.push({ value: str });
        }
      });
      cb(matches);
    };
  };
  var gravatars = gon.gravatars;
  var usernames = gon.usernames;
  $('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 1,
  },

  {
    name: 'usernames',
    displayKey: 'value',
    source: substringMatcher(usernames),
    templates: {
      empty: [
        '<div class="empty-message">',
        'No username matches found. Enter an email instead!',
        '</div>'
      ].join('\n'),
      suggestion: function(username){
        return  '<div id="user-selection">' +
                '<p><strong>' + username.value + '</strong></p>' +
                '<img src="' + gravatars[usernames.indexOf(username.value)] + '"/>' +
                '</div>' ;
      }
    }
  });
});


  • My final issue came with the highlighting. The highlight:true line within the typeahead method indicates that it should work right out of the box, but it did not for me (again, due to conflicting other assets). For this reason, I needed to debug in my JavaScript console, eventually finding that an item selected using typeahead was situated in a div with class of “tt-cursor”. A lot of the default styling was fine with me but, since the highlighting itself did not work, I added the following to my css, thus giving the selected item a background color. “` css styling.css div .tt-cursor { background-color: #16A085; } “` (that selector, “.tt-cursor”, was very important!)
  • And that concludes my adventures with typeahead. It took some time, but, as I described before, it’s those seemingly minor finishing touches that can end up taking the most time. This exercise was certainly proof of that. But it was worth it to get a working—and good-looking—typeahead form input.

    March 03, 2015

    Create A Sample Web Application On Rails

    Posted by Unknown
    0

     In this series I will create a simple web application. It includes the following main components: 

    • Mostly static pages, use bootstrap
    • Users can signin, signout, remember user signin
    •  Home page show all users, update their profiles, admin users can delete other users.
    • User can following or unfollow other users
    • Users can post articles, update and destroy their posts.
    • Users login and make their comments on articles.
    • Home page show all articles and current user profile, paging.
    • Build url for article
    • Simple search articles
    • Type ahead, use gon gem.

    Ok, start!

    Users, articles and some authorizations, validates...

    See more at : Rails Book

    The next articles: build friendly url, simple search box and type ahead on search box. 



    Popular Posts

    Labels

    Archive

     

    Blogroll

    Recepies

    Flickr Images

    Copyright © 2014. Tutorials Blog - All Rights Reserved