Friday, April 15, 2016

Rails: How to customise the order of fields in a form with nested fields | Fixed issues

Rails: How to customise the order of fields in a form with nested fields | Fixed issues


Rails: How to customise the order of fields in a form with nested fields

Posted: 15 Apr 2016 06:37 AM PDT

I have a form that saves attributes to two models Company and nested model Address in a single form using simple_nested_form_for and simple_fields_for.

The attributes:

Company:  -legal form  -website    Address:  -name  -uploads  

In my form I wish to change the order of the fields

-name (Address model)  -legal form (Company model)  -website (Address model)  -uploads (Company model)  

thus interchanging the form attributes and nested_field attributes

I tried the following, but that did not seem to work.

<%= simple_nested_form_for @company do |f| %>      <%= f.simple_fields_for :address do |c| %>          <%= c.input :name %>       <% end %>      <%= f.input :legal_form %>      <%= f.simple_fields_for :address do |c| %>          <%= c.input :website %>       <% end %>      <%= f.input :uploads %>  <% end %>  

How do I make this work?

How to asynchronously send JS variable to Rails

Posted: 15 Apr 2016 06:35 AM PDT

Simple HTML form in a view. I need the user selected value of the form to pass into the active record query when the user switches it. (Probably not params because then it won't be asynchronous?)

In the example below I need the business_id to be the value of the form. New to rails, so if you could provide some in page javascript, I'll deal with refactoring it to the resources later...

<select name="clients">    <option value="1">Tesla</option>    <option value="4">Chevy</option>  </select>    <table>    <% @clients.where(month_year:'2015-02',business_id:'NEED VALUE OF HTML FORM HERE').find_each do |client| %>      <tr>        <td><%= client.month_year %></td>        <td><%= client.business_id %></td>        <td><%= client.bill_charge %></td>      </tr>    <% end %>  </table>  

Rails production log level

Posted: 15 Apr 2016 06:49 AM PDT

I am using rails 4.2.6. And the log_level is :warn for production environment. But when I tail -f the production log file on server I am seeing that it logs at :info level. So the log file is getting bigger in a short time. I am really creazy. Is there any clue that how can I solve this issue?

why is AccessDenied returned for only some images in an S3 bucket?

Posted: 15 Apr 2016 06:25 AM PDT

I am using Carrierwave in a Rails app to upload image files to S3.

This has been working perfectly for some time.

Suddenly newly uploaded files are returning "AccessDenied". This only occurs when accessing the file via Cloudfront CDN references. If the direct S3 url is used, the image displays correctly.

I have an access policy and permissions set on the S3 bucket.

What is confusing me is why some files are returning Access Denied, whilst others are displaying correctly.

Examining the properties in S3, all files have the same permissions and policies, which are set at the bucket level.

What per-file settings can be set on S3 that would cause only some files to return Access Denied? And how are those settings configured?

Rails 4.2 Expire fragment cache

Posted: 15 Apr 2016 06:43 AM PDT

I am unable to expire a fragment cache.

In my view:

- cache(:later_orders, skip_digest: true) do    .col-md-12      .panel.panel-default        .panel-heading          %h5            = t('fahrner_erp.late_orders.title')  

In the controller's after_action:

def reset_fragment_cache    expire_fragment :late_orders  end  

In my server log:

Cache delete: views/late_orders  Expire fragment views/late_orders (0.2ms)  Completed 200 OK in 961ms (Views: 73.9ms | ActiveRecord: 30.5ms)  Started GET "/erp/late_orders" for 127.0.0.1 at 2016-04-15 15:09:37 +0200  Processing by FahrnerERP::LateOrdersController#index as HTML   User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 10]]  Cache read: views/later_orders ({:skip_digest=>true})  Read fragment views/later_orders (0.5ms)  

So we can see the expire_cache method is being called and expires the views/late_orders fragment. And just behind, after a page refresh, it reads the fragment again!

Why hasn't the fragment been properly deleted?

Rails migration error - table not showing in schema.rb

Posted: 15 Apr 2016 06:32 AM PDT

One of my model tables (Event) is not showing in the schema.rb file and in its place there is this message -

# Could not dump table "events" because of following NoMethodError  #   undefined method `[]' for nil:NilClass  

The last migration that was succesful was as follows -

class RemoveOrganiserDescriptionFromEvents < ActiveRecord::Migration    def change      remove_column :events, :organiser_description, :text    end  end  

Which was changed to this -

class AddOrganiserProfileToEvents < ActiveRecord::Migration    def change      add_column :events, :organiser_profile, :url    end  end  

I'm pretty sure its gone 'wonky' because the attribute shouldn't be a url it should be a string. However, when I try to perform other migrations it doesn't work. I get the following error in my terminal when I try and perform a rake db:migrate -

undefined method to_sym' for nil:NilClass Did you mean? to_s/Users/Michael/MWCoding/MamaKnows/mama_knows/db/migrate/20160415123947_remove_events_organiser_profile.rb:3:inchange' NoMethodError: undefined method `to_sym' for nil:NilClass Did you mean? to_s

In my migration files this was my code -

def change     change_column :events, :organiser_profile :string    end    def up    change_column :events, :organiser_profile, :string  end    def down    change_column :events, :organiser_profile, :url  end  

I've also tried to remove the column completely in an attempt to then replace it with the correct version but to no avail. All impending help would be appreciated.

Dynamically passing ids using slim instead of erb in ruby on rails

Posted: 15 Apr 2016 06:16 AM PDT

Hi I use slim in rails instead of erb. I need to generate dynamic ids based on the id of the record passed to the view page. This is a part of my code:

 #clear_class_"#{activity.id}"     - user = activity.user   .row     .col-xs-3.col-md-2.person_img     = link_to (image_tag user.avatar.url :normal, alt: user.full_name, class: 'img img-responsive'),  user_path(user)     ...  

when I try using #clear_class_"#{activity.id}" the view is getting distorted. How can I make this division a dynamic one with my activity id appended to the division id.

PostgreSQL data types excluding those for the row structure of tables

Posted: 15 Apr 2016 05:35 AM PDT

We're using Ruby on Rails 4.2.6 and PostgreSQL 9.3.10 for our multi-tenant application which creates a schema for each of our customers.

Within ActiveRecord there is code which executes the following SQL to fetch the data types:

SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype  FROM pg_type as t  LEFT JOIN pg_range as r ON oid = rngtypid  WHERE t.typname IN ('int2', 'int4', 'int8', 'oid', 'float4', 'float8', 'text', 'varchar', 'char', 'name', 'bpchar', 'bool', 'bit', 'varbit', 'timestamptz', 'date', 'time', 'money', 'bytea', 'point', 'hstore', 'json', 'jsonb', 'cidr', 'inet', 'uuid', 'xml', 'tsvector', 'macaddr', 'citext', 'ltree', 'interval', 'path', 'line', 'polygon', 'circle', 'lseg', 'box', 'timestamp', 'numeric')  OR t.typtype IN ('r', 'e', 'd')  OR t.typinput = 'array_in(cstring,oid,integer)'::regprocedure  OR t.typelem != 0  

As this query returns a record relating to the row structure of every table in every schema, the number of records exceeds 150k for our database. For example, for our tags table there is a record for every schema with a typname of "_tags", typinput of "array_in" and typtype of "b".

Could anyone recommend a way to alter this query to exclude these row structure records?

We have considered using the DISTINCT statement below but this would not cater for two "true" data types with the same name in different schemas.

DISTINCT ON (t.typname, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype)  

Prevent puma from running in locally (ruby on rails)

Posted: 15 Apr 2016 05:57 AM PDT

I'm recently started to use Puma for my production server with nginx, however, when I now try to run my app locally, it tries to run Puma with all my production settings and fails. How can I prevent Puma from running locally?

AFAIK all I've done was added the puma gem to my gemfile, so I don't know how it's accessing my server config (I'm just not too knowledgeable in this area). I have it in my production group:

group :production do    gem 'pg'    gem 'rails_12factor'    gem 'puma'  end  

Error:

→ rails s  => Booting Puma  => Rails 4.2.6 application starting in development on http://localhost:3000  => Run `rails server -h` for more startup options  => Ctrl-C to shutdown server  [8917] Puma starting in cluster mode...  [8917] * Version 3.4.0 (ruby 2.0.0-p645), codename: Owl Bowl Brawl  [8917] * Min threads: 1, max threads: 6  [8917] * Environment: development  [8917] * Process workers: 1  [8917] * Phased restart available  [8917] * Listening on tcp://localhost:3000  [8917] Use Ctrl-C to stop  /rbenv/versions/2.0.0-p645/lib/ruby/gems/2.0.0/gems/puma-3.4.0/lib/puma/runner.rb:103:in `reopen': No such file or directory - /Users/me/mll/shared/log/puma.stdout.log (Errno::ENOENT)  

Additionally, though less important to me right now, is it in my benefit to run Puma locally? If so, any tips/resources on how I can do that?

Multiple price groups per user per product: how to minimize amount of queries?

Posted: 15 Apr 2016 06:00 AM PDT

I have the following structures in my Rails (4.2) e-commerce application:

class Product < ActiveRecord::Base    has_many :prices      def best_price(price_groups)      prices.where(price_group_id: price_groups).minimum(:value)    end      def default_price      prices.where(price_group_id: 1).first.value    end    end    class Price < ActiveRecord::Base    belongs_to :price_group    belongs_to :product  end      class PriceGroup < ActiveRecord::Base    has_and_belongs_to_many :users    has_many :prices  end    class User < ActiveRecord::Base    has_and_belongs_to_many :price_groups  end  

Many users can be members of many price groups with many product price rows in each of them. There is a default group with default prices for each product plus there can be many optional price groups with special (reduced) product prices for some users. The problem is - this way I'm getting two queries per each product listed in my index page:

SELECT MIN("prices"."value") FROM "prices" WHERE "prices"."product_id" = $1 AND "prices"."price_group_id" IN (1, 2)  [["product_id", 3]]  

and

SELECT  "prices".* FROM "prices" WHERE "prices"."product_id" = $1 AND "prices"."price_group_id" = $2  ORDER BY "prices"."id" ASC LIMIT 1  [["product_id", 3], ["price_group_id", 1]]  

So, here is my question: Is there some (easy) way to load everything at once? Like getting list of product objects with default and minimum price fields. I understand how it can be done in a single SQL query, but I can't think of anything more natural, rails-activerecord-way.

How to Add to cart from external domain using Post Method in Rails

Posted: 15 Apr 2016 04:49 AM PDT

I have an app which needs to collect various product options and then make a post request to an external url (https://my-shop.myshopify.com/cart/add) and then redirect to that site with the items added to cart.

Unfortunately I can't simply use a cart permalink as I need lineitems to be included. So far I have this in my controller which successfully makes the post but doesn't redirect to the shopify site.

   def add_to_cart        @urlstring_to_post = 'https://my-shop.myshopify.com/cart/add'        #submit and get a result        @result = HTTParty.post(@urlstring_to_post.to_str,       :body => {:id => '15158758855',       :add => 'Add to Cart'      }.to_json,      :headers => { 'Content-Type' => 'application/json' } )        end  

undefined method `user_url' for Devise SessionsController:create

Posted: 15 Apr 2016 05:12 AM PDT

I have user model for authorization with devise gem. I want to add after_sign_in_path method:

# application_controller.rb    protected  # redirecting to appropriate url based on role    def after_sign_in_path_for(resource)      if current_user.has_role?(:admin)        dashboard_path      elsif current_user.has_role?(:student)        root_path      end    end
Whenever I try to sign in I get this error:

undefined method `user_url' for #<Devise::SessionsController:0x007fb89b5b00a8> Did you mean? course_url
I don't know why it says 'did you mean? course_url. But I have course model. And here are my routes:

authenticate :user do        resources :feeds, only: [:index]      resources :courses, only: [:index, :show]          # etc...      end

Also here is the code it points me:

if options.empty?              recipient.send(method, *args)    else              recipient.send(method, *args, options)    end

and first line of log:

actionpack (4.2.4) lib/action_dispatch/routing/polymorphic_routes.rb:220:in `polymorphic_method' 

Whenever I commend after_sign_in_path_for I am able to sign in. If I comment contents of after_sign_in_path_for but leave empty after_sign_in_path_for method, I also get this error.

EDIT: I tested that I am not also signed in, not just not redirected. I think error happens right in the call after_sign_in_path_for, not in the redirect_to or whatever. Probably it has to do something with resource.

EDIT2: here are my rake routes:

  new_user_session GET    /users/sign_in(.:format)          devise/sessions#new              user_session POST   /users/sign_in(.:format)          devise/sessions#create      destroy_user_session DELETE /users/sign_out(.:format)         devise/sessions#destroy             user_password POST   /users/password(.:format)         devise/passwords#create         new_user_password GET    /users/password/new(.:format)     devise/passwords#new        edit_user_password GET    /users/password/edit(.:format)    devise/passwords#edit                           PATCH  /users/password(.:format)         devise/passwords#update                           PUT    /users/password(.:format)         devise/passwords#update  cancel_user_registration GET    /users/cancel(.:format)           registrations#cancel         user_registration POST   /users(.:format)                  registrations#create     new_user_registration GET    /users/sign_up(.:format)          registrations#new    edit_user_registration GET    /users/edit(.:format)             registrations#edit                           PATCH  /users(.:format)                  registrations#update                           PUT    /users(.:format)                  registrations#update                           DELETE /users(.:format)                  registrations#destroy         user_confirmation POST   /users/confirmation(.:format)     devise/confirmations#create     new_user_confirmation GET    /users/confirmation/new(.:format) devise/confirmations#new                           GET    /users/confirmation(.:format)     devise/confirmations#show                admin_root GET    /                                 rails_admin/main#dashboard              student_root GET    /                                 feeds#index                     feeds GET    /feeds(.:format)                  feeds#index                   courses GET    /courses(.:format)                courses#index                    course GET    /courses/:id(.:format)            courses#show                   schools GET    /schools(.:format)                schools#index                    school GET    /schools/:id(.:format)            schools#show              universities GET    /universities(.:format)           universities#index                university GET    /universities/:id(.:format)       universities#show               rails_admin        /admin                            RailsAdmin::Engine                           POST   /graphql(.:format)                graphql#create      landing_confirmation GET    /landing/confirmation(.:format)   landing#confirmation     landing_access_denied GET    /landing/access_denied(.:format)  landing#access_denied                      root GET    /                                 landing#index

EDIT3: here is my github repo:

https://github.com/yerassyl/nurate

Convert Cordova Camera Captured Image File to File Object to save in Rails Application Database

Posted: 15 Apr 2016 04:34 AM PDT

I am developing ionic application where I am using Rails Api for backend. I am uploading file via camera capture plugins cordova-camera and cordova-file. I am getting the file which was stored in android phone cache. I need to upload this file into database along with the form input data. For that I need to convert it to a File Object.

For normal input file upload I have use ng-file-upload where it is retreiving file object where I ma saving in it backend sending as param like this:

"image"=>#<ActionController::UploadedStringIO:0xb4c9bae4>  

And ng-file-upload File object is lookig like this:

File {}  lastModified: 1460033422638  lastModifiedDate: Thu Apr 07 2016 18:20:22 GMT+0530 (IST)  name: "images.jpg"  size: 4003  type: "image/jpeg"  webkitRelativePath: ""  __proto__: File  

I need to save camera captured image as File Object so that I will send this File Object as parameter to rails action to save image in DB along with form input.

I have tried like this but no use in angularjs ionic app:

var options = new File();  options.fileKey = "file";  options.name = imageURI.substr(imageURI.lastIndexOf('/') + 1);  options.type = "image/jpeg";  var params = new Object();           params.imageURI = imageURI.substr(imageURI.lastIndexOf('/') + 1);           options.params = params;          options.chunkedMode = false;   

Can you please help me out regarding this.

Having a form for sending emails in rails

Posted: 15 Apr 2016 04:39 AM PDT

I'm new to rails and was wondering if there was a way to make a form in the views folder so that I can send an email. The form would need an input for: The email address; the subject; message.

Then basically you press send and it sends the email

Rails association callback with cached query

Posted: 15 Apr 2016 04:22 AM PDT

I have two models:

class Basket < ActiveRecord::Base    has_many :products      def recalculate_price!      price = products.map(&:price).sum      save    end  end    class Product < ActiveRecord::Base    belongs_to :basket      after_save :update_basket      def update_basket      basket.recalculate_price!    end  end  

and than I call it like this:

basket = Basket.new  basket.products.build(price)  basket.save  

The problem: basket.price don't update.

I've investigated the problem and found out that there is some kind of caching in update_basket method. The problem could be solved with placing reload before basket.recalculate_price!.

Is there any option to leave the update_basket method untouched? I have many such cases in my application.

I would like to understand how it works and avoid similar problems in the future.

note: I recently upgraded rails from 3.2 to 4.2. In a previous version everything worked fine.

Run method periodically in manualy created interval in Rails

Posted: 15 Apr 2016 04:12 AM PDT

I have a form when user can set day in week and time period (for example Monday from 02:00 to 03:00). Then I want to run specific method (periodically, for example every 30 seconds) but only during given time interval (it should be performed on background every Monday during 02:00 and 03:00, every 30 seconds). Is it possible to do this when time interval is created dynamically (by user)?

JSON serialization issue with Ember.js, Rails and Devise

Posted: 15 Apr 2016 04:07 AM PDT

I'm struggling to find a way of signing up a new user in my application. I've started using Ember and Rails a month ago and I'm not quite sure where the problem is. I can actually login with Devise and get data from my backend. I can create new instances of any models, except for users. After a week of reading and testing, I believe Devise is not using the user serializer and can't process my request.

Here's what I get when I request a new user registration :

Processing by Users::UsersController#create as JSON  Parameters: {"email"=>"qw.qw@we.we", "encrypted_password"=>"[FILTERED]", "firstname"=>"qw", "lastname"=>"qw", "user"=>{"email"=>"qw.qw@we.we", "encrypted_password"=>"[FILTERED]", "firstname"=>"qw", "lastname"=>"qw"}}  Can't verify CSRF token authenticity  (0.1ms)  begin transaction  User Exists (1.7ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = 'qw.qw@we.we' LIMIT 1  (0.1ms)  rollback transaction  [active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.2ms)  

And when I login:

Processing by SessionsController#create as JSON  Parameters: {"user"=>{"password"=>"[FILTERED]", "email"=>"test@test.com"}}  

Now here is my Ember serializer:

    import Ember from 'ember';        import DS from 'ember-data';      var underscore = Ember.String.underscore;        export default DS.JSONAPISerializer.extend({          keyForAttribute: function(attr) {          return underscore(attr);        },          keyForRelationship: function(rawKey) {          return underscore(rawKey);        },          serialize() {            const result = this._super(...arguments),           attr = result.data.attributes || {},           rel = result.data.relationships || {};            return Object.keys(rel).reduce(function(acc, elem) {           const data = rel[elem].data;           if (data) {             acc[elem + "_id"] = data.id;           }           if (data && data.type) {             acc[elem + "_type"] = data.type[0].toUpperCase() + data.type.slice(1, -1);           }           return acc;            }, attr);        }        });  

My adapter:

import DS from 'ember-data';  import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';    export default DS.JSONAPIAdapter.extend(DataAdapterMixin, {    authorizer: 'authorizer:application'  });  

And my client side:

  var userNew = this.get('store').createRecord('user', {      email: email,      password: password,      firstname: firstname,      lastname: lastname    });    userNew.save();  

The funny thing is I tried with the active-model-adapter addon. For some reasons I can register new users and login properly, but findRecord is giving me this error :

"Cannot read property '_internalModel' of undefined"  

Here's my gemfile:

gem 'rails', '4.2.6'  gem 'sqlite3'  gem 'sass-rails', '~> 5.0'  gem 'uglifier', '>= 1.3.0'  gem 'coffee-rails', '~> 4.1.0'  gem 'jquery-rails'  gem 'turbolinks'  gem 'jbuilder', '~> 2.0'  gem 'sdoc', '~> 0.4.0', group: :doc  gem 'rack-cors'  gem "devise", :github => 'plataformatec/devise', :branch => 'master'  gem 'omniauth-oauth2', '~> 1.3.1'  gem "omniauth-google-oauth2", :github => 'zquestz/omniauth-google-oauth2', :branch => 'master'  gem "active_model_serializers", github: "rails-api/active_model_serializers", :branch => 'master'  

And finally, my package.json:

"active-model-adapter": "2.1.1",  "broccoli-asset-rev": "^2.2.0",  "broccoli-clean-css": "1.1.0",  "ember-ajax": "0.7.1",  "ember-cli": "2.3.0",  "ember-cli-app-version": "^1.0.0",  "ember-cli-babel": "^5.1.5",  "ember-cli-dependency-checker": "^1.2.0",  "ember-cli-foundation-6-sass": "0.0.8",  "ember-cli-htmlbars": "^1.0.1",  "ember-cli-htmlbars-inline-precompile": "^0.3.1",  "ember-cli-ic-ajax": "0.2.4",  "ember-cli-inject-live-reload": "^1.3.1",  "ember-cli-qunit": "^1.2.1",  "ember-cli-release": "0.2.8",  "ember-cli-sass": "5.3.1",  "ember-cli-sri": "^2.0.0",  "ember-cli-star-rating": "0.4.0",  "ember-cli-uglify": "^1.2.0",  "ember-cp-validations": "2.6.1",  "ember-data": "^2.3.0",  "ember-disable-proxy-controllers": "^1.0.1",  "ember-export-application-global": "^1.0.4",  "ember-load-initializers": "^0.5.0",  "ember-masonry-grid": "1.1.0",  "ember-radio-button": "1.0.7",  "ember-resolver": "^2.0.3",  "ember-simple-auth": "1.0.1",  "loader.js": "^4.0.0",  "rails-csrf": "2.0.1",  "torii": "0.6.1"  

I feel like I'm missing something obvious, but can't figure out what...

rails check if a form was completely filled out

Posted: 15 Apr 2016 05:53 AM PDT

I have information in my rails view that I only want to show up if the user has entered all personal details in the database, such as name, firstname, street and city. I could now do this:

if user.name && user.firstname && user.street && user.street  # show stuff  end  

but I don't think that is very elegant and "the rails way". Is there an easier and smarter way to do this?

using .where with .find

Posted: 15 Apr 2016 06:41 AM PDT

I am wondering how I can use where cause with the ActiveRecord find method.

Here is the code I am using:

Supplier.joins(:products).find(params[:id]).where('suppliers.permalink = ? AND variants.master = ?', params[:id], TRUE)  

which gives me:

undefined method `where' for #<Supplier:0x007fe49b4eb330>  

Override attr_readonly in data migration to populate a new read only field on existing records

Posted: 15 Apr 2016 05:03 AM PDT

I have added a UUID field to an existing model. I want it to be read only so it cannot be changed.

Model:

class Token < ActiveRecord::Base    attr_readonly :uuid    before_create :set_uuid, on: create      def set_uuid      self.uuid = SecureRandom.urlsafe_base64(8)    end  end  

However I want to populate exiting records with UUIDs. I cannot do this through a default value because they are not generated dynamically.

I could write a custom validator in the model, but this seems like overkill when I only really want to override the attr_readonly in the data migration.

As it stands my data migration does not change the value for existing values from nil.

Data Migration:

class AddUuidToTokens < ActiveRecord::Migration    def self.up      Token.all.each do |token|      if token.uuid.nil?        token.uuid = SecureRandom.urlsafe_base64(8)        token.save!      end    end  end  

Solr Sunspot- specify which fields to return in the result

Posted: 15 Apr 2016 05:16 AM PDT

I'm using Sunspot Solr for indexing and searching in our Ruby on Rails application with MongoDB database (Mongo mapper)

Every time I queried Solr for result, it sends back the entire document content about the article stored in the database, which makes the query very slow.

What i want to do is to include only specific fields to the query.

I found that fl can be used to specify a set of fields to return but i'm getting an error, see blow:

searchable :if => :published do    text :title, :boost => 5  end    def self.search_keywords keywords    search = Top.search do      fulltext keywords      adjust_solr_params do |params|        params[:fl] = "title_text"      end    end    search.results  end  

Solr Request :

  SOLR Request (24.9ms)  [ path=select parameters={fq: ["type:Top"], q: "test", fl: "title_text", qf: "title_text", defType: "edismax", start: 0, rows: 30} ]  

Error :

undefined method `match' for nil:NilClass

Thanks.

Stream remote file to client in ruby/rails 4/unicorn/nginx

Posted: 15 Apr 2016 03:45 AM PDT

I am trying to stream a file from a remote storage service (not s3 :-)) to the client using Ruby on Rails 4.2.

My server needs to stay in the middle of things to authenticate the client request but also to build up the request to the remote storage service since all requests to that service need to be authenticated using a custom header param. This makes it not possible to do a simple redirect_to and let the client download the file directly (but do let me know if this IS in fact possible using rails!). Also I want to keep the url of the file cloaked for the client.

Up until now I am using a gem called ZipLine but this also does not work as it still buffers the remote file before sending it to the client. As I am using unicorn/nginx, this might also be due to a setting in either of those two, that prevents proper streaming.

As per rails doc's instructions I have tried adding

listen 3000, tcp_nopush: false  

to config/unicorn.rb but to no avail.

A solution might be to cache the remote file locally for a certain period and just serve that file. This would make some things easier but also creating new headaches like keeping the remote and cached files in sync, setting the right triggers for cache expiration, etc.

So to sum up:

1) How do I accomplish the scenario above?

2) If this is not a intelligent/efficient way of doing things, should I just cache a remote copy?

3) What are your experiences/recommendations in given scenario?

I have come across various solutions scattered around the interweb but none inspire a complete solution.

Thanks!

subdir in nginx for rails api-app

Posted: 15 Apr 2016 05:02 AM PDT

I am trying to configure the nginx to have a separate subdir for rails-5 api backend. (to separate frontend and backend)

Original, I am calling backend api under GET "/bills". Now I'd like to be it: GET '/api/bills'. so all requests under 'api' should be redirected to rails app.

But I can't make it working. The redirection works, but I see on rails side in logs: ActionController::RoutingError (No route matches [GET] "/api/bills"). Of course this route doesn't exists. Rails only knows about the "/bills" route. Could I configure nginx so, that the redirection would be transparent to Rails, and it would see the request like [GET]"/bills" ?

here is my current config:

upstream app {      # Path to Unicorn SOCK file, as defined previously      server unix:/var/sockets/unicorn.myapp.sock fail_timeout=0;  }    server {    #redirect to https          listen 0.0.0.0:80;    listen [::]:80 ipv6only=on default_server;    server_name localhost; ## Replace this with something like gitlab.example.com    server_tokens off; ## Don't show the nginx version number, a security best practice    return 301 https://$server_name$request_uri;    access_log  /var/log/nginx/app_access.log;    error_log   /var/log/nginx/app_error.log;  }      server {        listen 0.0.0.0:443 ssl;      listen [::]:443 ipv6only=on ssl default_server;      server_name localhost; ## Replace this with something like gitlab.example.com        ssl on;      ssl_certificate /etc/ssl/nginx/host.crt;      ssl_certificate_key /etc/ssl/nginx/host.key;        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;      ssl_prefer_server_ciphers on;      ssl_session_cache shared:SSL:10m;      ssl_session_timeout 5m;        location  ^~  /api {          #try_files $uri/index.html $uri $uri/;          try_files $uri/index.html $uri @app;          root /app/backend/public;      }          location @app {          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;          proxy_set_header Host $http_host;          proxy_redirect off;          proxy_pass http://app;            error_page 500 502 503 504 /500.html;      }          location / {        # Application Frontend root, as defined previously        try_files $uri $uri/ =404;        root /app/frontend/;      }          client_max_body_size 4G;      keepalive_timeout 10;  }  

Rails, product variants

Posted: 15 Apr 2016 06:16 AM PDT

I am building an e-commerce app the hard way(no spree, shoppe, etc) so that I can learn rails. Currently, I have a restaurant model, meals model, and orders model. Users(using devise) can open meals, fill in an order's form with an attribute :quantity and send the order to their carts(keeping :restaurant_id, meal_id, :qty). However, meals in restaurants normally have sizes and supplementals(with cheese, with ketchup, etc.). Ideally, I would build something like spree_flexi_variants but I just can't see how to do this... Should I nest "characteristics" and "supplementals"(becoming 2 levels deep as meals is currently nested in restaurant) in the meals, or somehow add an attribute to the meals model? Thank you guys for any suggestions!

Attachinary and javascript form

Posted: 15 Apr 2016 02:50 AM PDT

I have a form like this :

<%= simple_form_for @user, remote: true do |f| %>    <%= f.input :email %>    <%= f.input :photo, as: :attachinary %>    <%= f.button :submit %>  <% end %>  

My controller looks like this :

  def update      if @user.update(user_params)        respond_to do |format|          format.html { redirect_to user_path(@user) }          format.js        end      else        respond_to do |format|          format.html { render 'users/edit' }          format.js        end      end    end  

It works good with the HTML version but not with javascript version.

I know that browsers don't allow file upload via XMLHttpRequest, so I find a solution with remotipart gem, but it only considers <%= f.file_field :file %> and not my <%= f.input :photo, as: :attachinary %>

Devise login with username, signin failure not showing error message

Posted: 15 Apr 2016 03:23 AM PDT

I have been trying to login with username so followed this tutorial

https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address

Sign in with username and signup is happening perfectly. But if i try to sign in with invalid username or password, it is not showing any error messages.

i have <%= devise_error_messages! %> mentioned in sessions/new.html.erb. Also tried binding.pry resource doesn't have any errors attached to it.

routes.rb

devise_for :users  devise_scope :user do    root to: "devise/sessions#new"  end  

devise.rb

config.authentication_keys = [ :login ]  

other details same as mentioned in the url.

Showing User Profile

Posted: 15 Apr 2016 02:44 AM PDT

I've been trying to get this right and after hours I'm finally just lost. I'm attempting to create a profile for a user. I separated the profile model and user model because of the attributes and the types of user's I have. The user has a has_one relationship to the profile. My problem seems to be I'm confused with not only the routes but also the controller of the profile. I simply want to be able to have a link_to to show a user's profile. But on to the code

user.rb    has_one  :profile  after_create :create_profile  def create_profile    self.profile.create(:name => self.user_name)  end  

Profile model

profile.rb  belongs_to :user, required: true, autosave: true  

routes for profile

resources :profile   

profile controller

class ProfilesController < ApplicationController    before_action :owned_profile, only: [:edit]    before_action :get_profile    layout "profile"    respond_to :html, :js      def show      @activities = PublicActivity::Activity.where(owner:@user).order(created_at: :desc).paginate(page: params[:page], per_page: 10)    end      def followers      @followers = @user.user_followers.paginate(page: params[:page])    end      def edit    end      def update      if @profile.update(profile_params)        flash[:notices] = ["Your profile was successfully updated"]        render 'show'      else        flash[:notices] = ["Your profile could not be updated"]        render 'edit'      end    end      private      def profile_params      params.require(:profile).permit(:name, :cover)    end      def owned_profile      unless current_user == @user        flash[:alert] = "That profile doesn't belong to you!"        redirect_to root_path      end    end      def get_profile      @profile = Profile.find(params[:id])    end  end  

I'm completely lost on what I need to do, should I add something to the user's controller because of the after_create method? should my resources :profile be under resources :user?

The error I get when I try to view a user profile is Couldn't find Profile with 'id'=

the link_to method I am using is <%= link_to "View Profile", profiles_show_path(@user) %>

Please let me know anything that might be of help thank you for your time and help. again I don't want to just show a user's "show" as a profile because of the different types of user's and the way I plan to model the profiles.

How to add the ability to remove upvote or downvote on the second click?

Posted: 15 Apr 2016 03:25 AM PDT

Set my acts_as_votable, now the upvote and downvote buttons work properly but I want the user to remove his upvote on a second click like in facebook and twitter. Here's my controller

 def upvote        @post = Post.find        @post.downvote_by current_user    end      def downvote    @post = Post.find(params[:id])    @post.downvote_by current_user    end  

and the index

<%= link_to like_post_path(post), method: :put, class: 'upvote', remote: true  do %>                      Upvote                      <%= post.get_upvotes.size %>                  <% end %>                    <%= link_to dislike_post_path(post), method: :put, class: 'downvote', remote: true  do %>                      Downvote                      <%= post.get_downvotes.size %>                  <% end %>  

How can I achieve that?

Timetable App for Rails 4

Posted: 15 Apr 2016 02:57 AM PDT

I am trying to build a timetable setup to work in conjunction with one of my Models. Before I state my question, I will give some context into the problem.

I have a Model called Appointments with the following columns:

Name(String)  Start_time(time)  End_time(time)  Appt_Date(date)  

Now I can have multiple appointments in 1 day.

For Example, let's say I have the following 2 Appointment objects:

Appointment 1:   Name: Makeup Appointment  Start_time: 11:00 am  End_time: 1:00 pm  Date: March 30, 2016    Appointment 2:   Name: Daily Meetup  Start-time: 2:00 pm  End_time: 3:00 pm  Date: March 30, 2016  

I would like to implement a date-picker form where you can select a date and it would render 24 rows(1 for each hour of the day) and fill in the rows with the times not available based on the appointments on that day.

For example, if I select March 30, 2016 from the date-picker, I would like to render the 24 rows and have the rows for 11am-1pm and 2:00pm-3:00pm shaded out.

The setup is like google calendars(how time slots are colored in) but with a day-to-day basis. I don't need to be able to edit these rows. I just need to view them and have them rendered with colored cells based on Appointment objects for that specific day.

My issue is, I don't know where to begin to be able to design these 24 rows that interact with appointment objects. I was thinking that perhaps I build a helper method, however even that I am pretty lost. I would appreciate some guidance on how to approach this.

Rolling back Model-changes from action

Posted: 15 Apr 2016 02:16 AM PDT

I have the action, in where I assign groups to the members that apply. Basically, I just get a list of emails, from the view in a form, and then I have the action to catch it:

What I'm wondering is, that if I can rollback the changes that's been made already, if say the second member doesn't exist, or has a group already, how can I rollback these?

def group_create    @group = Group.new    params[:member].each { |m|      v = Volunteer.find_by_email(m[1])      raise "#{m[1]} doesn't exist" unless v.present?      raise "#{v.email} is already in a group" if v.group.present?      v.group = @group      v.save!    }    @group.save  rescue => error    flash[:error] = "Error: #{error}"  ensure    respond_to do |format|      unless flash[:error].present?        flash[:notice] = 'Group Application succeded.'        flash[:joined] = true        format.html { redirect_to apply_group_path }      else        flash.discard        format.html { render :group }      end    end  end  

What I've thought about already, was move the v.save and @group.save to the end, and make another loop of params[:member].each...., but that would be quite a waste of ressources, to do the find_by_email-method twice as many times, as needed.

No comments:

Post a Comment